org.openjdk.jmh.profile.AbstractHotspotProfiler Maven / Gradle / Ivy
/*
* Copyright (c) 2005, 2013, 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.openjdk.jmh.profile;
import org.openjdk.jmh.infra.BenchmarkParams;
import org.openjdk.jmh.infra.IterationParams;
import org.openjdk.jmh.results.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
abstract class AbstractHotspotProfiler implements InternalProfiler {
private final Method getListMethod;
private final Object bean;
private Map prevs;
public AbstractHotspotProfiler(String beanName, String methodName) throws ProfilerException {
try {
Class> helper = Class.forName("sun.management.ManagementFactoryHelper");
bean = helper.getMethod("get" + beanName).invoke(null);
getListMethod = bean.getClass().getMethod(methodName);
getListMethod.setAccessible(true);
getListMethod.invoke(bean); // try
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new ProfilerException("Problem initializing profiler (" + e.getMessage() + "), are you running HotSpot VM?");
}
}
@Override
public Collection extends Result> afterIteration(BenchmarkParams benchmarkParams, IterationParams iterationParams, IterationResult result) {
HotspotInternalResult res = counters();
Collection results = new ArrayList<>();
for (Map.Entry e : res.getDiff().entrySet()) {
results.add(new ScalarResult(Defaults.PREFIX + e.getKey(), e.getValue(), "?", AggregationPolicy.AVG));
}
return results;
}
@Override
public void beforeIteration(BenchmarkParams benchmarkParams, IterationParams iterationParams) {
prevs = new HashMap<>();
for (HotspotCounter counter : getCounters()) {
prevs.put(counter.getName(), convert(counter.getValue()));
}
}
public static Long convert(Object o) {
try {
return Long.valueOf(String.valueOf(o));
} catch (IllegalArgumentException iae) {
return null;
}
}
protected HotspotInternalResult counters() {
Map difference = new TreeMap<>();
Map current = new TreeMap<>();
for (HotspotCounter counter : getCounters()) {
Long prev = prevs.get(counter.getName());
if (prev != null) {
long diff = convert(counter.getValue()) - prev;
difference.put(counter.getName(), diff);
current.put(counter.getName(), convert(counter.getValue()));
}
}
return new HotspotInternalResult(current, difference);
}
public List getCounters() {
try {
List counters = new ArrayList<>();
for (Object c : (List) getListMethod.invoke(bean)) {
try {
counters.add(new HotspotCounter(c));
} catch (UnsupportedOperationException e) {
// ignore this counter
}
}
return counters;
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Should not be here", e);
}
}
/**
* Represents the HotSpot profiling result.
*/
static class HotspotInternalResult {
private final Map current;
private final Map diff;
public HotspotInternalResult(Map current, Map diff) {
this.current = current;
this.diff = diff;
}
public Map getCurrent() {
return current;
}
public Map getDiff() {
return diff;
}
@Override
public String toString() {
return "difference: " + diff.toString();
}
}
/**
* Reflective proxy for Hotspot counters to dodge compatibility problems.
*/
private static class HotspotCounter {
private static final Method GET_VALUE;
private static final Method GET_NAME;
static {
Method name = null;
Method value = null;
try {
Class> cntClass = Class.forName("sun.management.counter.Counter");
if (cntClass != null) {
try {
name = cntClass.getMethod("getName");
} catch (NoSuchMethodException e) {
// do nothing
}
try {
value = cntClass.getMethod("getValue");
} catch (NoSuchMethodException e) {
// do nothing
}
}
} catch (ClassNotFoundException e) {
// no nothing
}
GET_NAME = name;
GET_VALUE = value;
}
private final Object proxy;
public HotspotCounter(Object proxy) throws UnsupportedOperationException {
this.proxy = proxy;
// Try these right now
if (GET_NAME == null || GET_VALUE == null) {
throw new UnsupportedOperationException();
}
try {
String k = (String) GET_NAME.invoke(proxy);
Object v = GET_VALUE.invoke(proxy);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}
public String getName() {
try {
return (String) GET_NAME.invoke(proxy);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Cannot be here");
}
}
public Object getValue() {
try {
return GET_VALUE.invoke(proxy);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Cannot be here");
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy