HotSpotGraalMBean.java revision 13083:b9a173f12fe6
1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.hotspot;
24
25import java.lang.management.ManagementFactory;
26import java.lang.reflect.Field;
27import java.util.ArrayList;
28import java.util.Iterator;
29import java.util.List;
30import javax.management.Attribute;
31import javax.management.AttributeList;
32import javax.management.AttributeNotFoundException;
33import javax.management.DynamicMBean;
34import javax.management.InstanceAlreadyExistsException;
35import javax.management.InvalidAttributeValueException;
36import javax.management.MBeanAttributeInfo;
37import javax.management.MBeanException;
38import javax.management.MBeanInfo;
39import javax.management.MBeanRegistrationException;
40import javax.management.MBeanServer;
41import javax.management.MalformedObjectNameException;
42import javax.management.NotCompliantMBeanException;
43import javax.management.ObjectName;
44import javax.management.ReflectionException;
45import jdk.vm.ci.meta.ResolvedJavaMethod;
46import org.graalvm.compiler.options.OptionDescriptor;
47import org.graalvm.compiler.options.OptionDescriptors;
48import org.graalvm.compiler.options.OptionKey;
49import org.graalvm.compiler.options.OptionValues;
50import org.graalvm.compiler.options.OptionsParser;
51import org.graalvm.util.EconomicMap;
52
53public final class HotSpotGraalMBean implements DynamicMBean {
54    private static Object mBeanServerField;
55    private final OptionValues options;
56    private final EconomicMap<OptionKey<?>, Object> changes;
57    private ObjectName registered;
58
59    private HotSpotGraalMBean(OptionValues options) {
60        this.options = options;
61        this.changes = EconomicMap.create();
62    }
63
64    private static boolean isMXServerOn() {
65        if (mBeanServerField == null) {
66            try {
67                final Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer");
68                field.setAccessible(true);
69                mBeanServerField = field;
70            } catch (Exception ex) {
71                mBeanServerField = ManagementFactory.class;
72            }
73        }
74        if (mBeanServerField instanceof Field) {
75            try {
76                return ((Field) mBeanServerField).get(null) != null;
77            } catch (Exception ex) {
78                return true;
79            }
80        } else {
81            return false;
82        }
83    }
84
85    public static HotSpotGraalMBean create() {
86        OptionValues options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
87        HotSpotGraalMBean mbean = new HotSpotGraalMBean(options);
88        return mbean;
89    }
90
91    public ObjectName ensureRegistered(boolean check) {
92        for (int cnt = 0;; cnt++) {
93            if (registered != null) {
94                return registered;
95            }
96            if (check && !isMXServerOn()) {
97                return null;
98            }
99            try {
100                MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
101                ObjectName name = new ObjectName("org.graalvm.compiler.hotspot:type=Options" + (cnt == 0 ? "" : cnt));
102                mbs.registerMBean(this, name);
103                registered = name;
104                break;
105            } catch (MalformedObjectNameException | MBeanRegistrationException | NotCompliantMBeanException ex) {
106                throw new IllegalStateException(ex);
107            } catch (InstanceAlreadyExistsException ex) {
108                continue;
109            }
110        }
111        return registered;
112    }
113
114    @SuppressWarnings("unused")
115    OptionValues optionsFor(OptionValues values, ResolvedJavaMethod forMethod) {
116        ensureRegistered(true);
117        if (changes.isEmpty()) {
118            return values;
119        }
120        return new OptionValues(values, changes);
121    }
122
123    @Override
124    public Object getAttribute(String attribute) {
125        for (OptionKey<?> k : options.getMap().getKeys()) {
126            if (k.getName().equals(attribute)) {
127                return options.getMap().get(k);
128            }
129        }
130        return null;
131    }
132
133    @Override
134    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
135        throw new InvalidAttributeValueException();
136    }
137
138    @Override
139    public AttributeList getAttributes(String[] names) {
140        AttributeList list = new AttributeList();
141        for (String name : names) {
142            Object value = getAttribute(name);
143            if (value != null) {
144                list.add(new Attribute(name, value));
145            }
146        }
147        return list;
148    }
149
150    @Override
151    public AttributeList setAttributes(AttributeList attributes) {
152        throw new IllegalStateException();
153    }
154
155    @Override
156    public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
157        return null;
158    }
159
160    @Override
161    public MBeanInfo getMBeanInfo() {
162        List<MBeanAttributeInfo> attrs = new ArrayList<>();
163        if (registered != null) {
164            for (Iterator<OptionDescriptors> it = OptionsParser.getOptionsLoader().iterator(); it.hasNext();) {
165                for (OptionDescriptor descr : it.next()) {
166                    attrs.add(new MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, false, false));
167                }
168            }
169        }
170        return new MBeanInfo(
171                        HotSpotGraalMBean.class.getName(),
172                        "Graal",
173                        attrs.toArray(new MBeanAttributeInfo[attrs.size()]),
174                        null, null, null);
175    }
176
177}
178