1b66cecd31
Reviewed-by: kvn
164 lines
5.5 KiB
Java
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();
|
|
}
|
|
}
|