--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java Mon Apr 23 12:53:43 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
-import jdk.vm.ci.meta.MetaUtil;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.runtime.JVMCI;
-
-import org.graalvm.compiler.debug.DebugOptions;
-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.collections.EconomicMap;
-import org.graalvm.collections.EconomicSet;
-import org.graalvm.collections.Equivalence;
-import org.graalvm.collections.UnmodifiableEconomicMap;
-
-public final class HotSpotGraalMBean implements javax.management.DynamicMBean {
- private static Object mBeanServerField;
- private final HotSpotGraalCompiler compiler;
- private final OptionValues options;
- private final EconomicMap<OptionKey<?>, Object> changes;
- private final EconomicSet<Dump> methodDumps;
- private volatile EconomicSet<Reference<ClassLoader>> loaders;
- private javax.management.ObjectName registered;
- private OptionValues cachedOptions;
-
- private HotSpotGraalMBean(HotSpotGraalCompiler compiler, OptionValues options) {
- this.compiler = compiler;
- this.options = options;
- this.changes = EconomicMap.create();
- this.methodDumps = EconomicSet.create();
- EconomicSet<Reference<ClassLoader>> systemLoaderSet = EconomicSet.create(RefEquivalence.INSTANCE);
- systemLoaderSet.add(new WeakReference<>(ClassLoader.getSystemClassLoader()));
- this.loaders = systemLoaderSet;
- }
-
- private static boolean isMXServerOn() {
- if (mBeanServerField == null) {
- try {
- final Field field = java.lang.management.ManagementFactory.class.getDeclaredField("platformMBeanServer");
- field.setAccessible(true);
- mBeanServerField = field;
- } catch (Exception ex) {
- mBeanServerField = java.lang.management.ManagementFactory.class;
- }
- }
- if (mBeanServerField instanceof Field) {
- try {
- return ((Field) mBeanServerField).get(null) != null;
- } catch (Exception ex) {
- return true;
- }
- } else {
- return false;
- }
- }
-
- public static HotSpotGraalMBean create(HotSpotGraalCompiler compiler) {
- OptionValues options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
- HotSpotGraalMBean mbean = new HotSpotGraalMBean(compiler, options);
- return mbean;
- }
-
- public javax.management.ObjectName ensureRegistered(boolean check) {
- for (int cnt = 0;; cnt++) {
- if (registered != null) {
- return registered;
- }
- if (check && !isMXServerOn()) {
- return null;
- }
- try {
- javax.management.MBeanServer mbs = java.lang.management.ManagementFactory.getPlatformMBeanServer();
- javax.management.ObjectName name = new javax.management.ObjectName("org.graalvm.compiler.hotspot:type=Options" + (cnt == 0 ? "" : cnt));
- mbs.registerMBean(this, name);
- registered = name;
- break;
- } catch (javax.management.MalformedObjectNameException | javax.management.MBeanRegistrationException | javax.management.NotCompliantMBeanException ex) {
- throw new IllegalStateException(ex);
- } catch (javax.management.InstanceAlreadyExistsException ex) {
- continue;
- }
- }
- return registered;
- }
-
- public OptionValues optionsFor(OptionValues initialValues, ResolvedJavaMethod forMethod) {
- ensureRegistered(true);
- if (forMethod instanceof HotSpotResolvedJavaMethod) {
- HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) forMethod).getDeclaringClass();
- if (type instanceof HotSpotResolvedJavaType) {
- Class<?> clazz = ((HotSpotResolvedJavaType) type).mirror();
- Reference<ClassLoader> addNewRef = new WeakReference<>(clazz.getClassLoader());
- if (!loaders.contains(addNewRef)) {
- EconomicSet<Reference<ClassLoader>> newLoaders = EconomicSet.create(RefEquivalence.INSTANCE, loaders);
- newLoaders.add(addNewRef);
- this.loaders = newLoaders;
- }
- }
- }
- return currentMap(initialValues, forMethod);
- }
-
- private OptionValues currentMap(OptionValues initialValues, ResolvedJavaMethod method) {
- if (changes.isEmpty() && methodDumps.isEmpty()) {
- return initialValues;
- }
- OptionValues current = cachedOptions;
- if (current == null) {
- current = new OptionValues(initialValues, changes);
- cachedOptions = current;
- }
- if (method != null) {
- for (Dump request : methodDumps) {
- final String clazzName = method.getDeclaringClass().getName();
- if (method.getName().equals(request.method) && clazzName.equals(request.clazz)) {
- current = new OptionValues(current, DebugOptions.Dump, request.filter,
- DebugOptions.PrintGraphHost, request.host,
- DebugOptions.PrintBinaryGraphPort, request.port);
- break;
- }
- }
- }
- return current;
- }
-
- @Override
- public Object getAttribute(String attribute) {
- UnmodifiableEconomicMap<OptionKey<?>, Object> map = currentMap(options, null).getMap();
- for (OptionKey<?> k : map.getKeys()) {
- if (k.getName().equals(attribute)) {
- return map.get(k);
- }
- }
- return null;
- }
-
- @Override
- public void setAttribute(javax.management.Attribute attribute) throws javax.management.AttributeNotFoundException {
- javax.management.Attribute newAttr = setImpl(attribute);
- if (newAttr == null) {
- throw new javax.management.AttributeNotFoundException();
- }
- }
-
- private javax.management.Attribute setImpl(javax.management.Attribute attribute) {
- cachedOptions = null;
- for (OptionDescriptor option : allOptionDescriptors()) {
- if (option.getName().equals(attribute.getName())) {
- changes.put(option.getOptionKey(), attribute.getValue());
- return attribute;
- }
- }
- return null;
- }
-
- @Override
- public javax.management.AttributeList getAttributes(String[] names) {
- javax.management.AttributeList list = new javax.management.AttributeList();
- for (String name : names) {
- Object value = getAttribute(name);
- if (value != null) {
- list.add(new javax.management.Attribute(name, value));
- }
- }
- return list;
- }
-
- @Override
- public javax.management.AttributeList setAttributes(javax.management.AttributeList attributes) {
- javax.management.AttributeList setOk = new javax.management.AttributeList();
- for (javax.management.Attribute attr : attributes.asList()) {
- javax.management.Attribute newAttr = setImpl(attr);
- if (newAttr != null) {
- setOk.add(newAttr);
- }
- }
- return setOk;
- }
-
- @Override
- public Object invoke(String actionName, Object[] params, String[] signature) throws javax.management.MBeanException, javax.management.ReflectionException {
- if ("dumpMethod".equals(actionName)) {
- try {
- 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());
- } catch (Exception ex) {
- throw new javax.management.ReflectionException(ex);
- }
- }
- 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);
- }
-
- public void dumpMethod(String className, String methodName, String filter, String host, int port) throws javax.management.MBeanException {
- String jvmName = MetaUtil.toInternalName(className);
- methodDumps.add(new Dump(host, port, jvmName, methodName, filter));
-
- ClassNotFoundException last = null;
- EconomicSet<Class<?>> found = EconomicSet.create();
- Iterator<Reference<ClassLoader>> it = loaders.iterator();
- while (it.hasNext()) {
- Reference<ClassLoader> ref = it.next();
- ClassLoader loader = ref.get();
- if (loader == null) {
- it.remove();
- continue;
- }
- try {
- Class<?> clazz = Class.forName(className, false, loader);
- if (found.add(clazz)) {
- ResolvedJavaType type = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaType(clazz);
- if (compiler != null) {
- for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
- if (methodName.equals(method.getName()) && method instanceof HotSpotResolvedJavaMethod) {
- HotSpotResolvedJavaMethod hotSpotMethod = (HotSpotResolvedJavaMethod) method;
- compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false);
- }
- }
- }
- }
- } catch (ClassNotFoundException ex) {
- last = ex;
- }
- }
- if (found.isEmpty()) {
- throw new javax.management.MBeanException(last, "Cannot find class " + className + " to schedule recompilation");
- }
- }
-
- @Override
- public javax.management.MBeanInfo getMBeanInfo() {
- List<javax.management.MBeanAttributeInfo> attrs = new ArrayList<>();
- for (OptionDescriptor descr : allOptionDescriptors()) {
- attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
- }
- javax.management.MBeanOperationInfo[] ops = {
- new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
- new javax.management.MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
- new javax.management.MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
- }, "void", javax.management.MBeanOperationInfo.ACTION),
- new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
- new javax.management.MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
- new javax.management.MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
- new javax.management.MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
- }, "void", javax.management.MBeanOperationInfo.ACTION),
- new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
- new javax.management.MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
- new javax.management.MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
- new javax.management.MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
- new javax.management.MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
- new javax.management.MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
- }, "void", javax.management.MBeanOperationInfo.ACTION)
- };
-
- return new javax.management.MBeanInfo(
- HotSpotGraalMBean.class.getName(),
- "Graal",
- attrs.toArray(new javax.management.MBeanAttributeInfo[attrs.size()]),
- null, ops, null);
- }
-
- private static Iterable<OptionDescriptor> allOptionDescriptors() {
- List<OptionDescriptor> arr = new ArrayList<>();
- for (OptionDescriptors set : OptionsParser.getOptionsLoader()) {
- for (OptionDescriptor descr : set) {
- arr.add(descr);
- }
- }
- return arr;
- }
-
- private static final class Dump {
- final String host;
- final int port;
- final String clazz;
- final String method;
- final String filter;
-
- Dump(String host, int port, String clazz, String method, String filter) {
- this.host = host;
- this.port = port;
- this.clazz = clazz;
- this.method = method;
- this.filter = filter;
- }
- }
-
- private static final class RefEquivalence extends Equivalence {
- static final Equivalence INSTANCE = new RefEquivalence();
-
- private RefEquivalence() {
- }
-
- @Override
- public boolean equals(Object a, Object b) {
- Reference<?> refA = (Reference<?>) a;
- Reference<?> refB = (Reference<?>) b;
- return Objects.equals(refA.get(), refB.get());
- }
-
- @Override
- public int hashCode(Object o) {
- Reference<?> ref = (Reference<?>) o;
- Object obj = ref.get();
- return obj == null ? 0 : obj.hashCode();
- }
-
- }
-}