# HG changeset patch
# User shade
# Date 1511362328 -3600
# Node ID f5ac05188aa1cd6116f1cfab67e7e6875e17d32e
# Parent 0cb1442be9d6e079b3e6d1bf7f65f3e0f537a6cd
Autogenerate class roots tests
diff -r 0cb1442be9d6 -r f5ac05188aa1 pom.xml
--- a/pom.xml Thu Oct 26 17:04:09 2017 +0200
+++ b/pom.xml Wed Nov 22 15:52:08 2017 +0100
@@ -66,6 +66,11 @@
${jmh.version}
provided
+
+ org.ow2.asm
+ asm
+ 5.0.3
+
diff -r 0cb1442be9d6 -r f5ac05188aa1 src/main/java/org/openjdk/gcbench/roots/ClassGenerator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/gcbench/roots/ClassGenerator.java Wed Nov 22 15:52:08 2017 +0100
@@ -0,0 +1,75 @@
+package org.openjdk.gcbench.roots;
+
+import org.objectweb.asm.*;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.objectweb.asm.Opcodes.*;
+
+public class ClassGenerator {
+
+ private static final int CLASSFILE_VERSION = 50;
+
+ private static final AtomicInteger idx = new AtomicInteger();
+
+
+ public static Class> generate(ByteClassLoader cl) throws Exception {
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+ String name = "Class" + idx.incrementAndGet();
+
+ cw.visit(CLASSFILE_VERSION,
+ ACC_PUBLIC + ACC_SUPER,
+ name,
+ null,
+ Type.getInternalName(Object.class),
+ new String[0]);
+
+ cw.visitSource(name + ".java", null);
+
+ {
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+
+ cw.visitField(ACC_STATIC, "ref", "Ljava/lang/Object;", "Ljava/lang/Object;", null);
+
+ cw.visitEnd();
+
+ cl.put(name, cw.toByteArray());
+ return cl.findClass(name);
+ }
+
+ public static class ByteClassLoader extends URLClassLoader {
+ private final Map customClasses;
+
+ public ByteClassLoader() {
+ super(new URL[] {});
+ customClasses = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ protected Class> findClass(final String name) throws ClassNotFoundException {
+ if (customClasses.containsKey(name)) {
+ byte[] bs = customClasses.get(name);
+ return defineClass(name, bs, 0, bs.length);
+ }
+ return super.findClass(name);
+ }
+
+ public void put(String name, byte[] bytes) {
+ customClasses.put(name, bytes);
+ }
+ }
+
+}
\ No newline at end of file
diff -r 0cb1442be9d6 -r f5ac05188aa1 src/main/java/org/openjdk/gcbench/roots/Classes.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/gcbench/roots/Classes.java Wed Nov 22 15:52:08 2017 +0100
@@ -0,0 +1,44 @@
+package org.openjdk.gcbench.roots;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Threads(Threads.MAX)
+@State(Scope.Benchmark)
+public class Classes {
+
+ @Param({"1", "10", "1000", "10000", "100000"})
+ int classes;
+
+ @Param({"1", "10", "100", "1000"})
+ int classloaders;
+
+ Class>[] arr;
+ ClassGenerator.ByteClassLoader[] cls;
+
+ @Setup
+ public void setup() throws Exception {
+ arr = new Class[classes];
+ cls = new ClassGenerator.ByteClassLoader[classloaders];
+ int classesPerCl = classes / classloaders;
+ for (int c = 0; c < classloaders; c++) {
+ cls[c] = new ClassGenerator.ByteClassLoader();
+ for (int v = 0; v < classesPerCl; v++) {
+ arr[c*classesPerCl + v] = ClassGenerator.generate(cls[c]);
+ }
+ }
+ }
+
+ @Benchmark
+ public Object test() {
+ return new Object();
+ }
+
+}
diff -r 0cb1442be9d6 -r f5ac05188aa1 src/main/java/org/openjdk/gcbench/roots/Code.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/gcbench/roots/Code.java Wed Nov 22 15:52:08 2017 +0100
@@ -0,0 +1,29 @@
+package org.openjdk.gcbench.roots;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Threads(Threads.MAX)
+@State(Scope.Thread)
+public class Code {
+
+ static final MyIntHolder constant = new MyIntHolder();
+
+ @Benchmark
+ public int test() {
+ return constant.x;
+ }
+
+ static class MyIntHolder {
+ int x;
+ }
+}
diff -r 0cb1442be9d6 -r f5ac05188aa1 src/main/java/org/openjdk/gcbench/roots/NewSync.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/gcbench/roots/NewSync.java Wed Nov 22 15:52:08 2017 +0100
@@ -0,0 +1,51 @@
+package org.openjdk.gcbench.roots;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Threads(Threads.MAX)
+@State(Scope.Benchmark)
+public class NewSync {
+
+ SyncPair[] pairs;
+
+ @Param({"100000"})
+ int size;
+
+ @Setup
+ public void setup() {
+ pairs = new SyncPair[size];
+ for (int c = 0; c < size; c++) {
+ pairs[c] = new SyncPair();
+ }
+ }
+
+ @TearDown(Level.Iteration)
+ public void gc() {
+ System.gc();
+ }
+
+ @Benchmark
+ public void test() throws InterruptedException {
+ for (SyncPair pair : pairs) {
+ pair.move();
+ }
+ }
+
+ static class SyncPair {
+ int x, y;
+ public synchronized void move() {
+ x++;
+ y--;
+ }
+ }
+
+}
diff -r 0cb1442be9d6 -r f5ac05188aa1 src/main/java/org/openjdk/gcbench/roots/NewSyncReentrant.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/gcbench/roots/NewSyncReentrant.java Wed Nov 22 15:52:08 2017 +0100
@@ -0,0 +1,57 @@
+package org.openjdk.gcbench.roots;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Threads(Threads.MAX)
+@State(Scope.Benchmark)
+public class NewSyncReentrant {
+
+ SyncPair[] pairs;
+
+ @Param({"100000"})
+ int size;
+
+ @Setup
+ public void setup() {
+ pairs = new SyncPair[size];
+ for (int c = 0; c < size; c++) {
+ pairs[c] = new SyncPair();
+ }
+ }
+
+ @TearDown(Level.Iteration)
+ public void gc() {
+ System.gc();
+ }
+
+ @Benchmark
+ public void test() throws InterruptedException {
+ for (SyncPair pair : pairs) {
+ pair.move();
+ }
+ }
+
+ static class SyncPair {
+ final ReentrantLock lock = new ReentrantLock();
+ int x, y;
+
+ public void move() {
+ lock.lock();
+ try {
+ x++;
+ y--;
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+}
diff -r 0cb1442be9d6 -r f5ac05188aa1 src/main/java/org/openjdk/gcbench/roots/ReentrantLocks.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/gcbench/roots/ReentrantLocks.java Wed Nov 22 15:52:08 2017 +0100
@@ -0,0 +1,45 @@
+package org.openjdk.gcbench.roots;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Fork(1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Threads(Threads.MAX)
+@State(Scope.Thread)
+public class ReentrantLocks {
+
+ List list;
+
+ @Param({"40000"})
+ private int size;
+
+ @Setup
+ public void setup() {
+ list = new ArrayList<>();
+ for (int c = 0; c < size; c++) {
+ list.add(new ReentrantLock());
+ }
+ }
+
+ @Benchmark
+ public void test(Blackhole bh) throws InterruptedException {
+ for (ReentrantLock lock : list) {
+ lock.lock();
+ }
+ bh.consume(new byte[100000]);
+ for (ReentrantLock lock : list) {
+ lock.newCondition().await(1, TimeUnit.NANOSECONDS);
+ lock.unlock();
+ }
+ }
+
+}