package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.debug.MemUseTrackerKey.getCurrentThreadAllocatedBytes;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.core.test.AllocSpy;
import org.graalvm.compiler.hotspot.CompilationTask;
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.runtime.JVMCICompiler;
public class MemoryUsageBenchmark extends HotSpotGraalCompilerTest {
public static int simple(int a, int b) {
return a + b;
}
public static synchronized int complex(CharSequence cs) {
if (cs instanceof String) {
return cs.hashCode();
}
if (cs instanceof StringBuilder) {
int[] hash = {0};
cs.chars().forEach(c -> hash[0] += c);
return hash[0];
}
int res = 0;
synchronized (cs) {
res = cs.length();
}
synchronized (cs) {
res = cs.hashCode() ^ 31;
}
for (int i = 0; i < cs.length(); i++) {
res *= cs.charAt(i);
}
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += i * 2;
}
res += sum;
res += new String("asdf").length();
return res;
}
static class MemoryUsageCloseable implements AutoCloseable {
private final long start;
private final String name;
MemoryUsageCloseable(String name) {
this.name = name;
this.start = getCurrentThreadAllocatedBytes();
}
@Override
public void close() {
long end = getCurrentThreadAllocatedBytes();
long allocated = end - start;
System.out.println(name + ": " + allocated);
}
}
public static void main(String[] args) {
Graal.getRuntime();
new MemoryUsageBenchmark().run();
}
@SuppressWarnings("try")
private void doCompilation(String methodName, String label) {
HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) getResolvedJavaMethod(methodName);
method.reprofile();
long jvmciEnv = 0L;
try (MemoryUsageCloseable c = label == null ? null : new MemoryUsageCloseable(label)) {
HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI;
HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, jvmciEnv);
CompilationTask task = new CompilationTask(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), request, true, false);
task.runCompilation(getInitialOptions());
}
}
@SuppressWarnings("try")
private void allocSpyCompilation(String methodName) {
if (AllocSpy.isEnabled()) {
HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) getResolvedJavaMethod(methodName);
method.reprofile();
long jvmciEnv = 0L;
try (AllocSpy as = AllocSpy.open(methodName)) {
HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, JVMCICompiler.INVOCATION_ENTRY_BCI, jvmciEnv);
HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler();
OptionValues options = getInitialOptions();
CompilationTask task = new CompilationTask(runtime, compiler, request, true, false);
task.runCompilation(options);
}
}
}
private static final boolean verbose = Boolean.getBoolean("verbose");
private void compileAndTime(String methodName) {
parseEager(methodName, AllowAssumptions.YES);
for (int i = 0; i < 10; i++) {
doCompilation(methodName, verbose ? methodName + "[warmup-" + i + "]" : null);
}
doCompilation(methodName, methodName);
}
public void run() {
compileAndTime("simple");
compileAndTime("complex");
OptionValues harnessOptions = CompileTheWorld.loadHarnessOptions();
if (CompileTheWorld.Options.Classpath.getValue(harnessOptions) != CompileTheWorld.SUN_BOOT_CLASS_PATH) {
HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
CompileTheWorld ctw = new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), harnessOptions, getInitialOptions());
try {
ctw.compile();
} catch (Throwable e) {
e.printStackTrace();
}
}
allocSpyCompilation("simple");
allocSpyCompilation("complex");
}
}