1b66cecd31
Reviewed-by: kvn
211 lines
7.1 KiB
Java
211 lines
7.1 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.Param;
|
|
import org.openjdk.jmh.annotations.Scope;
|
|
import org.openjdk.jmh.annotations.State;
|
|
import org.openjdk.jmh.annotations.Warmup;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/**
|
|
* Test spill code generation.
|
|
*/
|
|
@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 SpillCode {
|
|
|
|
@Param("10")
|
|
private int iterations;
|
|
|
|
private int dummy;
|
|
|
|
private int doSomeCalcsInLargeBlockWithInts(int start, int iter) {
|
|
|
|
int a1, a2, a3, a4;
|
|
int b1, b2, b3, b4;
|
|
int c1, c2, c3, c4;
|
|
int d1, d2, d3, d4;
|
|
int e1, e2, e3, e4;
|
|
int f1, f2, f3, f4;
|
|
int g1, g2, g3, g4;
|
|
int h1, h2, h3, h4;
|
|
|
|
// a1 = b1 = c1 = d1 = e1 = f1 = g1 = h1 = (start % 2);
|
|
a2 = b2 = c2 = d2 = e2 = f2 = g2 = h2 = (start % 2);
|
|
a3 = b3 = c3 = d3 = e3 = f3 = g3 = h3 = (start % 4);
|
|
a4 = b4 = c4 = d4 = e4 = f4 = g4 = h4 = (start % 8);
|
|
|
|
for (int i = 0; i < iter; i++) {
|
|
|
|
// for each section, only x1 needs to survive.
|
|
|
|
// a1 = a2 = a3 = a4 = (start + a1) % 2;
|
|
a1 = start;
|
|
a1 = a1 + a2 + a3 + a4;
|
|
a2 = a1 + a2 + a3 + a4;
|
|
a3 = a1 + a2 + a3 + a4;
|
|
a4 = a1 + a2 + a3 + a4;
|
|
a1 = a1 + a2 + a3 + a4;
|
|
a2 = a1 + a2 + a3 + a4;
|
|
a3 = a1 + a2 + a3 + a4;
|
|
a4 = a1 + a2 + a3 + a4;
|
|
a1 = a1 + a2 + a3 + a4;
|
|
a2 = a1 + a2 + a3 + a4;
|
|
a3 = a1 + a2 + a3 + a4;
|
|
a4 = a1 + a2 + a3 + a4;
|
|
|
|
// b1 = b2 = b3 = b4 = (a4 + b1) % 2;
|
|
b1 = a4;
|
|
b1 = b1 + b2 + b3 + b4;
|
|
b2 = b1 + b2 + b3 + b4;
|
|
b3 = b1 + b2 + b3 + b4;
|
|
b4 = b1 + b2 + b3 + b4;
|
|
b1 = b1 + b2 + b3 + b4;
|
|
b2 = b1 + b2 + b3 + b4;
|
|
b3 = b1 + b2 + b3 + b4;
|
|
b4 = b1 + b2 + b3 + b4;
|
|
b1 = b1 + b2 + b3 + b4;
|
|
b2 = b1 + b2 + b3 + b4;
|
|
b3 = b1 + b2 + b3 + b4;
|
|
b4 = b1 + b2 + b3 + b4;
|
|
|
|
// c1 = c2 = c3 = c4 = (b4 + c1) % 2;
|
|
c1 = b4;
|
|
c1 = c1 + c2 + c3 + c4;
|
|
c2 = c1 + c2 + c3 + c4;
|
|
c3 = c1 + c2 + c3 + c4;
|
|
c4 = c1 + c2 + c3 + c4;
|
|
c1 = c1 + c2 + c3 + c4;
|
|
c2 = c1 + c2 + c3 + c4;
|
|
c3 = c1 + c2 + c3 + c4;
|
|
c4 = c1 + c2 + c3 + c4;
|
|
c1 = c1 + c2 + c3 + c4;
|
|
c2 = c1 + c2 + c3 + c4;
|
|
c3 = c1 + c2 + c3 + c4;
|
|
c4 = c1 + c2 + c3 + c4;
|
|
|
|
// d1 = d2 = d3 = d4 = (c4 + d1) % 2;
|
|
d1 = c4;
|
|
d1 = d1 + d2 + d3 + d4;
|
|
d2 = d1 + d2 + d3 + d4;
|
|
d3 = d1 + d2 + d3 + d4;
|
|
d4 = d1 + d2 + d3 + d4;
|
|
d1 = d1 + d2 + d3 + d4;
|
|
d2 = d1 + d2 + d3 + d4;
|
|
d3 = d1 + d2 + d3 + d4;
|
|
d4 = d1 + d2 + d3 + d4;
|
|
d1 = d1 + d2 + d3 + d4;
|
|
d2 = d1 + d2 + d3 + d4;
|
|
d3 = d1 + d2 + d3 + d4;
|
|
d4 = d1 + d2 + d3 + d4;
|
|
|
|
// e1 = e2 = e3 = e4 = (d4 + e1) % 2;
|
|
e1 = d4;
|
|
e1 = e1 + e2 + e3 + e4;
|
|
e2 = e1 + e2 + e3 + e4;
|
|
e3 = e1 + e2 + e3 + e4;
|
|
e4 = e1 + e2 + e3 + e4;
|
|
e1 = e1 + e2 + e3 + e4;
|
|
e2 = e1 + e2 + e3 + e4;
|
|
e3 = e1 + e2 + e3 + e4;
|
|
e4 = e1 + e2 + e3 + e4;
|
|
e1 = e1 + e2 + e3 + e4;
|
|
e2 = e1 + e2 + e3 + e4;
|
|
e3 = e1 + e2 + e3 + e4;
|
|
e4 = e1 + e2 + e3 + e4;
|
|
|
|
// f1 = f2 = f3 = f4 = (e4 + f1) % 2;
|
|
f1 = e4;
|
|
f1 = f1 + f2 + f3 + f4;
|
|
f2 = f1 + f2 + f3 + f4;
|
|
f3 = f1 + f2 + f3 + f4;
|
|
f4 = f1 + f2 + f3 + f4;
|
|
f1 = f1 + f2 + f3 + f4;
|
|
f2 = f1 + f2 + f3 + f4;
|
|
f3 = f1 + f2 + f3 + f4;
|
|
f4 = f1 + f2 + f3 + f4;
|
|
f1 = f1 + f2 + f3 + f4;
|
|
f2 = f1 + f2 + f3 + f4;
|
|
f3 = f1 + f2 + f3 + f4;
|
|
f4 = f1 + f2 + f3 + f4;
|
|
|
|
// g1 = g2 = g3 = g4 = (f4 + g1) % 2;
|
|
g1 = f4;
|
|
g1 = g1 + g2 + g3 + g4;
|
|
g2 = g1 + g2 + g3 + g4;
|
|
g3 = g1 + g2 + g3 + g4;
|
|
g4 = g1 + g2 + g3 + g4;
|
|
g1 = g1 + g2 + g3 + g4;
|
|
g2 = g1 + g2 + g3 + g4;
|
|
g3 = g1 + g2 + g3 + g4;
|
|
g4 = g1 + g2 + g3 + g4;
|
|
g1 = g1 + g2 + g3 + g4;
|
|
g2 = g1 + g2 + g3 + g4;
|
|
g3 = g1 + g2 + g3 + g4;
|
|
g4 = g1 + g2 + g3 + g4;
|
|
|
|
// h1 = h2 = h3 = h4 = (g4 + h1) % 2;
|
|
h1 = g4;
|
|
h1 = h1 + h2 + h3 + h4;
|
|
h2 = h1 + h2 + h3 + h4;
|
|
h3 = h1 + h2 + h3 + h4;
|
|
h4 = h1 + h2 + h3 + h4;
|
|
h1 = h1 + h2 + h3 + h4;
|
|
h2 = h1 + h2 + h3 + h4;
|
|
h3 = h1 + h2 + h3 + h4;
|
|
h4 = h1 + h2 + h3 + h4;
|
|
h1 = h1 + h2 + h3 + h4;
|
|
h2 = h1 + h2 + h3 + h4;
|
|
h3 = h1 + h2 + h3 + h4;
|
|
h4 = h1 + h2 + h3 + h4;
|
|
|
|
start = h4;
|
|
}
|
|
|
|
return start;
|
|
}
|
|
|
|
/**
|
|
* The test runs a loop with many local variables. The issue it reproduces is that if handled wrong, too many variables
|
|
* are put on and referenced on stack. The number of iterations is taken from global variable, to prevent static loop
|
|
* unrolling. Many of the variables used in the larger loop are local inside the block and do dnot need to survive from
|
|
* one iteration to the next.
|
|
*/
|
|
@Benchmark
|
|
public int testSpillForManyInts() throws Exception {
|
|
return doSomeCalcsInLargeBlockWithInts(dummy, iterations);
|
|
}
|
|
}
|