jdk-24/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java
2022-08-03 18:01:26 +00:00

164 lines
5.5 KiB
Java

/*
* Copyright (c) 2014, 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.openjdk.bench.vm.compiler;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS)
@Fork(value = 3)
public class WriteBarrier {
// For array references
public static final int NUM_REFERENCES_SMALL = 32;
public static final int NUM_REFERENCES_LARGE = 2048;
// For array update tests
private Object[] theArraySmall;
private Object[] realReferencesSmall;
private Object[] nullReferencesSmall;
private int[] indicesSmall;
private Object[] theArrayLarge;
private Object[] realReferencesLarge;
private Object[] nullReferencesLarge;
private int[] indicesLarge;
// For field update tests
public Referencer head = null;
public Referencer tail = null;
// For random number generation
private int m_w;
private int m_z;
// For field references
public class Referencer {
Referencer next = null;
Referencer() {
this.next = null;
}
void append(Referencer r) {
this.next = r;
}
void clear() {
this.next = null;
}
}
@Setup
public void setup() {
theArraySmall = new Object[NUM_REFERENCES_SMALL];
realReferencesSmall = new Object[NUM_REFERENCES_SMALL];
nullReferencesSmall = new Object[NUM_REFERENCES_SMALL];
indicesSmall = new int[NUM_REFERENCES_SMALL];
theArrayLarge = new Object[NUM_REFERENCES_LARGE];
realReferencesLarge = new Object[NUM_REFERENCES_LARGE];
nullReferencesLarge = new Object[NUM_REFERENCES_LARGE];
indicesLarge = new int[NUM_REFERENCES_LARGE];
m_w = (int) System.currentTimeMillis();
Random random = new Random();
m_z = random.nextInt(10000) + 1;
for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
indicesSmall[i] = get_random() % (NUM_REFERENCES_SMALL - 1);
realReferencesSmall[i] = new Object();
}
for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
indicesLarge[i] = get_random() % (NUM_REFERENCES_LARGE - 1);
realReferencesLarge[i] = new Object();
}
// Build a small linked structure
this.head = new Referencer();
this.tail = new Referencer();
this.head.append(this.tail);
// This will (hopefully) promote objects to old space
// Run with -XX:+DisableExplicitGC to keep
// objects in young space
System.gc();
}
private int get_random() {
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return Math.abs((m_z << 16) + m_w); /* 32-bit result */
}
@Benchmark
public void testArrayWriteBarrierFastPathRealSmall() {
for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = realReferencesSmall[indicesSmall[i]];
}
}
@Benchmark
public void testArrayWriteBarrierFastPathNullSmall() {
for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = nullReferencesSmall[indicesSmall[i]];
}
}
@Benchmark
public void testArrayWriteBarrierFastPathRealLarge() {
for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = realReferencesLarge[indicesLarge[i]];
}
}
@Benchmark
public void testArrayWriteBarrierFastPathNullLarge() {
for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = nullReferencesLarge[indicesLarge[i]];
}
}
@Benchmark()
public void testFieldWriteBarrierFastPath() {
// Shuffle everything around
this.tail.append(this.head);
this.head.clear();
this.head.append(this.tail);
this.tail.clear();
}
}