diff options
| author | 2024-08-15 15:56:48 +0100 | |
|---|---|---|
| committer | 2024-08-16 11:29:08 +0000 | |
| commit | 30970448e676c29c283d7b43a2f5115abc004ca0 (patch) | |
| tree | a2bc81e49ff6ac16ddbc14574f47e776f5097b4f | |
| parent | 73a49cd990a10d7e21d41be001170e72e6ba3d49 (diff) | |
Separate the varhandle-perf tests
This was the most time consuming test by far.
Locally with 72 threads:
* The 2239- tests take 24s instead of 2m40s.
* Running the whole test suite now takes 1m30 instead of 3m.
The test generation can be moved to utils since it can be reused between
tests.
Test: Build the tests and then run
time art/test/testrunner/testrunner.py --host --64 \
--optimizing -t 2239-
Test: Same but without -t 2239-
Change-Id: Ibc2c230d8afd617ee674429fe8e42543ddb140a1
156 files changed, 4398 insertions, 91 deletions
diff --git a/test/2239-varhandle-perf/build.py b/test/2239-varhandle-perf-vh-cae/build.py index 3466dfece7..3466dfece7 100644 --- a/test/2239-varhandle-perf/build.py +++ b/test/2239-varhandle-perf-vh-cae/build.py diff --git a/test/2239-varhandle-perf/expected-stderr.txt b/test/2239-varhandle-perf-vh-cae/expected-stderr.txt index e69de29bb2..e69de29bb2 100644 --- a/test/2239-varhandle-perf/expected-stderr.txt +++ b/test/2239-varhandle-perf-vh-cae/expected-stderr.txt diff --git a/test/2239-varhandle-perf/expected-stdout.txt b/test/2239-varhandle-perf-vh-cae/expected-stdout.txt index e69de29bb2..e69de29bb2 100644 --- a/test/2239-varhandle-perf/expected-stdout.txt +++ b/test/2239-varhandle-perf-vh-cae/expected-stdout.txt diff --git a/test/2239-varhandle-perf/generate-sources b/test/2239-varhandle-perf-vh-cae/generate-sources index 310ad06f46..37d3173dba 100755 --- a/test/2239-varhandle-perf/generate-sources +++ b/test/2239-varhandle-perf-vh-cae/generate-sources @@ -27,4 +27,5 @@ GENERATED_SRC=src2 mkdir -p src2 # Generate tests and Main that covers both the generated tests and manual tests -python3 ./util-src/generate_java.py "${GENERATED_SRC}" +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 4 diff --git a/test/2239-varhandle-perf/info.txt b/test/2239-varhandle-perf-vh-cae/info.txt index 943303dfaf..943303dfaf 100644 --- a/test/2239-varhandle-perf/info.txt +++ b/test/2239-varhandle-perf-vh-cae/info.txt diff --git a/test/2239-varhandle-perf/run.py b/test/2239-varhandle-perf-vh-cae/run.py index 4e8755dbda..4e8755dbda 100644 --- a/test/2239-varhandle-perf/run.py +++ b/test/2239-varhandle-perf-vh-cae/run.py diff --git a/test/2239-varhandle-perf/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-cae/src/BenchmarkBase.java index ee390b46ad..ee390b46ad 100644 --- a/test/2239-varhandle-perf/src/BenchmarkBase.java +++ b/test/2239-varhandle-perf-vh-cae/src/BenchmarkBase.java diff --git a/test/2239-varhandle-perf/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-cae/src/MicroBenchmark.java index bd72f58842..bd72f58842 100644 --- a/test/2239-varhandle-perf/src/MicroBenchmark.java +++ b/test/2239-varhandle-perf-vh-cae/src/MicroBenchmark.java diff --git a/test/2239-varhandle-perf/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-cae/src/UnsafeMicroBenchmark.java index 1b8c0af959..1b8c0af959 100644 --- a/test/2239-varhandle-perf/src/UnsafeMicroBenchmark.java +++ b/test/2239-varhandle-perf-vh-cae/src/UnsafeMicroBenchmark.java diff --git a/test/2239-varhandle-perf-vh-cas-weak/build.py b/test/2239-varhandle-perf-vh-cas-weak/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-cas-weak/expected-stderr.txt b/test/2239-varhandle-perf-vh-cas-weak/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-cas-weak/expected-stdout.txt b/test/2239-varhandle-perf-vh-cas-weak/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-cas-weak/generate-sources b/test/2239-varhandle-perf-vh-cas-weak/generate-sources new file mode 100755 index 0000000000..c35a2046c6 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 3 diff --git a/test/2239-varhandle-perf-vh-cas-weak/info.txt b/test/2239-varhandle-perf-vh-cas-weak/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-cas-weak/run.py b/test/2239-varhandle-perf-vh-cas-weak/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-cas-weak/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-cas-weak/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-cas-weak/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-cas-weak/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-cas-weak/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-cas-weak/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas-weak/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-cas/build.py b/test/2239-varhandle-perf-vh-cas/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-cas/expected-stderr.txt b/test/2239-varhandle-perf-vh-cas/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-cas/expected-stdout.txt b/test/2239-varhandle-perf-vh-cas/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-cas/generate-sources b/test/2239-varhandle-perf-vh-cas/generate-sources new file mode 100755 index 0000000000..e525622dbd --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 2 diff --git a/test/2239-varhandle-perf-vh-cas/info.txt b/test/2239-varhandle-perf-vh-cas/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-cas/run.py b/test/2239-varhandle-perf-vh-cas/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-cas/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-cas/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-cas/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-cas/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-cas/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-cas/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-cas/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-gaa/build.py b/test/2239-varhandle-perf-vh-gaa/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-gaa/expected-stderr.txt b/test/2239-varhandle-perf-vh-gaa/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-gaa/expected-stdout.txt b/test/2239-varhandle-perf-vh-gaa/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-gaa/generate-sources b/test/2239-varhandle-perf-vh-gaa/generate-sources new file mode 100755 index 0000000000..d1e0825282 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 6 diff --git a/test/2239-varhandle-perf-vh-gaa/info.txt b/test/2239-varhandle-perf-vh-gaa/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-gaa/run.py b/test/2239-varhandle-perf-vh-gaa/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-gaa/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-gaa/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-gaa/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-gaa/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-gaa/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-gaa/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gaa/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-gab/build.py b/test/2239-varhandle-perf-vh-gab/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-gab/expected-stderr.txt b/test/2239-varhandle-perf-vh-gab/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-gab/expected-stdout.txt b/test/2239-varhandle-perf-vh-gab/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-gab/generate-sources b/test/2239-varhandle-perf-vh-gab/generate-sources new file mode 100755 index 0000000000..783ca2d10f --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 7 diff --git a/test/2239-varhandle-perf-vh-gab/info.txt b/test/2239-varhandle-perf-vh-gab/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-gab/run.py b/test/2239-varhandle-perf-vh-gab/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-gab/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-gab/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-gab/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-gab/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-gab/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-gab/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gab/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-gas/build.py b/test/2239-varhandle-perf-vh-gas/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-gas/expected-stderr.txt b/test/2239-varhandle-perf-vh-gas/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-gas/expected-stdout.txt b/test/2239-varhandle-perf-vh-gas/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-gas/generate-sources b/test/2239-varhandle-perf-vh-gas/generate-sources new file mode 100755 index 0000000000..7d43ccac15 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 5 diff --git a/test/2239-varhandle-perf-vh-gas/info.txt b/test/2239-varhandle-perf-vh-gas/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-gas/run.py b/test/2239-varhandle-perf-vh-gas/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-gas/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-gas/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-gas/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-gas/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-gas/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-gas/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-gas/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-get-a/build.py b/test/2239-varhandle-perf-vh-get-a/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-get-a/expected-stderr.txt b/test/2239-varhandle-perf-vh-get-a/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-get-a/expected-stdout.txt b/test/2239-varhandle-perf-vh-get-a/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-get-a/generate-sources b/test/2239-varhandle-perf-vh-get-a/generate-sources new file mode 100755 index 0000000000..a42ba79bc7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 8 diff --git a/test/2239-varhandle-perf-vh-get-a/info.txt b/test/2239-varhandle-perf-vh-get-a/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-get-a/run.py b/test/2239-varhandle-perf-vh-get-a/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-get-a/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-get-a/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-get-a/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-get-a/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-get-a/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-get-a/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-a/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-get-bav/build.py b/test/2239-varhandle-perf-vh-get-bav/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-get-bav/expected-stderr.txt b/test/2239-varhandle-perf-vh-get-bav/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-get-bav/expected-stdout.txt b/test/2239-varhandle-perf-vh-get-bav/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-get-bav/generate-sources b/test/2239-varhandle-perf-vh-get-bav/generate-sources new file mode 100755 index 0000000000..dfa73f776c --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 10 diff --git a/test/2239-varhandle-perf-vh-get-bav/info.txt b/test/2239-varhandle-perf-vh-get-bav/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-get-bav/run.py b/test/2239-varhandle-perf-vh-get-bav/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-get-bav/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-get-bav/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-get-bav/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-get-bav/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-get-bav/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-get-bav/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get-bav/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-get/build.py b/test/2239-varhandle-perf-vh-get/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-get/expected-stderr.txt b/test/2239-varhandle-perf-vh-get/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-get/expected-stdout.txt b/test/2239-varhandle-perf-vh-get/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-get/generate-sources b/test/2239-varhandle-perf-vh-get/generate-sources new file mode 100755 index 0000000000..adc1384a29 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 0 diff --git a/test/2239-varhandle-perf-vh-get/info.txt b/test/2239-varhandle-perf-vh-get/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-get/run.py b/test/2239-varhandle-perf-vh-get/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-get/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-get/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-get/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-get/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-get/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-get/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-get/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-reflect-get/build.py b/test/2239-varhandle-perf-vh-reflect-get/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-reflect-get/expected-stderr.txt b/test/2239-varhandle-perf-vh-reflect-get/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-reflect-get/expected-stdout.txt b/test/2239-varhandle-perf-vh-reflect-get/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-reflect-get/generate-sources b/test/2239-varhandle-perf-vh-reflect-get/generate-sources new file mode 100755 index 0000000000..35cb71dad8 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 12 diff --git a/test/2239-varhandle-perf-vh-reflect-get/info.txt b/test/2239-varhandle-perf-vh-reflect-get/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-reflect-get/run.py b/test/2239-varhandle-perf-vh-reflect-get/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-reflect-get/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-reflect-get/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-reflect-get/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-reflect-get/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-reflect-get/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-reflect-get/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-get/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-reflect-set/build.py b/test/2239-varhandle-perf-vh-reflect-set/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-reflect-set/expected-stderr.txt b/test/2239-varhandle-perf-vh-reflect-set/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-reflect-set/expected-stdout.txt b/test/2239-varhandle-perf-vh-reflect-set/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-reflect-set/generate-sources b/test/2239-varhandle-perf-vh-reflect-set/generate-sources new file mode 100755 index 0000000000..3424c2eccb --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 13 diff --git a/test/2239-varhandle-perf-vh-reflect-set/info.txt b/test/2239-varhandle-perf-vh-reflect-set/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-reflect-set/run.py b/test/2239-varhandle-perf-vh-reflect-set/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-reflect-set/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-reflect-set/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-reflect-set/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-reflect-set/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-reflect-set/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-reflect-set/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-reflect-set/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-set-a/build.py b/test/2239-varhandle-perf-vh-set-a/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-set-a/expected-stderr.txt b/test/2239-varhandle-perf-vh-set-a/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-set-a/expected-stdout.txt b/test/2239-varhandle-perf-vh-set-a/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-set-a/generate-sources b/test/2239-varhandle-perf-vh-set-a/generate-sources new file mode 100755 index 0000000000..e839f958b1 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 9 diff --git a/test/2239-varhandle-perf-vh-set-a/info.txt b/test/2239-varhandle-perf-vh-set-a/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-set-a/run.py b/test/2239-varhandle-perf-vh-set-a/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-set-a/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-set-a/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-set-a/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-set-a/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-set-a/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-set-a/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-a/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-set-bav/build.py b/test/2239-varhandle-perf-vh-set-bav/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-set-bav/expected-stderr.txt b/test/2239-varhandle-perf-vh-set-bav/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-set-bav/expected-stdout.txt b/test/2239-varhandle-perf-vh-set-bav/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-set-bav/generate-sources b/test/2239-varhandle-perf-vh-set-bav/generate-sources new file mode 100755 index 0000000000..25fc18071e --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 11 diff --git a/test/2239-varhandle-perf-vh-set-bav/info.txt b/test/2239-varhandle-perf-vh-set-bav/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-set-bav/run.py b/test/2239-varhandle-perf-vh-set-bav/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-set-bav/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-set-bav/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-set-bav/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-set-bav/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-set-bav/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-set-bav/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set-bav/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-set/build.py b/test/2239-varhandle-perf-vh-set/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-set/expected-stderr.txt b/test/2239-varhandle-perf-vh-set/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-set/expected-stdout.txt b/test/2239-varhandle-perf-vh-set/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-set/generate-sources b/test/2239-varhandle-perf-vh-set/generate-sources new file mode 100755 index 0000000000..280169c167 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 1 diff --git a/test/2239-varhandle-perf-vh-set/info.txt b/test/2239-varhandle-perf-vh-set/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-set/run.py b/test/2239-varhandle-perf-vh-set/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-set/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-set/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-set/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-set/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-set/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-set/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-set/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/build.py b/test/2239-varhandle-perf-vh-unsafe-cas/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/expected-stderr.txt b/test/2239-varhandle-perf-vh-unsafe-cas/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/expected-stdout.txt b/test/2239-varhandle-perf-vh-unsafe-cas/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/generate-sources b/test/2239-varhandle-perf-vh-unsafe-cas/generate-sources new file mode 100755 index 0000000000..18fdc5fccf --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 16 diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/info.txt b/test/2239-varhandle-perf-vh-unsafe-cas/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/run.py b/test/2239-varhandle-perf-vh-unsafe-cas/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-unsafe-cas/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-unsafe-cas/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-unsafe-cas/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-unsafe-cas/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-cas/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-unsafe-get/build.py b/test/2239-varhandle-perf-vh-unsafe-get/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-unsafe-get/expected-stderr.txt b/test/2239-varhandle-perf-vh-unsafe-get/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-unsafe-get/expected-stdout.txt b/test/2239-varhandle-perf-vh-unsafe-get/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-unsafe-get/generate-sources b/test/2239-varhandle-perf-vh-unsafe-get/generate-sources new file mode 100755 index 0000000000..84c2f702cd --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 14 diff --git a/test/2239-varhandle-perf-vh-unsafe-get/info.txt b/test/2239-varhandle-perf-vh-unsafe-get/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-unsafe-get/run.py b/test/2239-varhandle-perf-vh-unsafe-get/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-unsafe-get/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-unsafe-get/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-unsafe-get/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-unsafe-get/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-unsafe-get/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-unsafe-get/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-get/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-unsafe-put/build.py b/test/2239-varhandle-perf-vh-unsafe-put/build.py new file mode 100644 index 0000000000..3466dfece7 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/build.py @@ -0,0 +1,22 @@ +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def build(ctx): + ctx.bash("./generate-sources") + if ctx.jvm: + return # The test does not build on JVM + + ctx.default_build(api_level="var-handles") diff --git a/test/2239-varhandle-perf-vh-unsafe-put/expected-stderr.txt b/test/2239-varhandle-perf-vh-unsafe-put/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/expected-stderr.txt diff --git a/test/2239-varhandle-perf-vh-unsafe-put/expected-stdout.txt b/test/2239-varhandle-perf-vh-unsafe-put/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/expected-stdout.txt diff --git a/test/2239-varhandle-perf-vh-unsafe-put/generate-sources b/test/2239-varhandle-perf-vh-unsafe-put/generate-sources new file mode 100755 index 0000000000..b5abcbf29b --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/generate-sources @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make us exit on a failure +set -e + +# Set variables for source directories. Using src-art so we use +# VarHandles in the bootclasspath and can compile with the Java 8 +# compiler. +MANUAL_SRC=src +GENERATED_SRC=src2 + +# Build the Java files +mkdir -p src2 + +# Generate tests and Main that covers both the generated tests and manual tests +python3 ${ANDROID_BUILD_TOP}/art/test/utils/python/generate_java_varhandle_perf.py \ +"${GENERATED_SRC}" 15 diff --git a/test/2239-varhandle-perf-vh-unsafe-put/info.txt b/test/2239-varhandle-perf-vh-unsafe-put/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf-vh-unsafe-put/run.py b/test/2239-varhandle-perf-vh-unsafe-put/run.py new file mode 100644 index 0000000000..4e8755dbda --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/run.py @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def run(ctx, args): + ctx.default_run(args) + + # Dump the output of the benchmarks that run and report success. The + # benchmarks ran successfully if we get as far as this script. + ctx.run(fr"cat '{args.stdout_file}'") + + # Delete all output to make the diff unconditionally pass. + ctx.run(fr"> '{args.stdout_file}'") diff --git a/test/2239-varhandle-perf-vh-unsafe-put/src/BenchmarkBase.java b/test/2239-varhandle-perf-vh-unsafe-put/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/src/BenchmarkBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class BenchmarkBase { + public final String name; + + // Empty constructor. + public BenchmarkBase(String name) { + this.name = name; + } + + // The benchmark code. + // This function is not used, if both [warmup] and [exercise] are overwritten. + public void run() throws Throwable { } + + // Runs a short version of the benchmark. By default invokes [run] once. + public void warmup() throws Throwable { + run(); + } + + // Exercises the benchmark. By default invokes [run] 10 times. + public void exercise() throws Throwable { + for (int i = 0; i < 10; ++i) { + run(); + } + } + + // Not measured setup code executed prior to the benchmark runs. + public void setup() throws Throwable { } + + // Not measures teardown code executed after the benchark runs. + public void teardown() throws Throwable { } + + // Measures the score for this benchmark by executing it repeatedly until + // time minimum has been reached. + protected double measureFor(boolean doWarmup, long timeMinimum) throws Throwable { + int iter = 0; + long startTime = System.currentTimeMillis(); + long elapsed = 0; + while (elapsed < timeMinimum) { + if (doWarmup) { + warmup(); + } else { + exercise(); + } + elapsed = System.currentTimeMillis() - startTime; + iter++; + } + return 1000.0 * elapsed / iter; + } + + // Measures the score for the benchmark and returns it. + public double measure() throws Throwable { + setup(); + // Warmup for at least 100ms. Discard result. + measureFor(true, 100); + // Run the benchmark for at least 1000ms. + double result = measureFor(false, 1000); + teardown(); + return result; + } + + // Allow subclasses to override how the name is printed. + public String getName() { + return name; + } + + public void report() throws Throwable { + double score = measure(); + System.out.println(getName() + "(RunTime): " + score + " us."); + } +}
\ No newline at end of file diff --git a/test/2239-varhandle-perf-vh-unsafe-put/src/MicroBenchmark.java b/test/2239-varhandle-perf-vh-unsafe-put/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/src/MicroBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.PrintStream; + +class MicroBenchmark extends BenchmarkBase { + private static final int EXERCISE_ITERATIONS = 1000; + + MicroBenchmark() { + super(null); + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public void exercise() throws Throwable { + for (int i = 0; i < EXERCISE_ITERATIONS; ++i) { + run(); + } + } + + public int innerIterations() { + return 1; + } + + @Override + public void report() { + try { + double microseconds = measure() / (EXERCISE_ITERATIONS * innerIterations()); + System.out.println(getName() + "(RunTimeRaw): " + microseconds + " us."); + } catch (Throwable t) { + System.err.println("Exception during the execution of " + getName()); + System.err.println(t); + t.printStackTrace(new PrintStream(System.err)); + System.exit(1); + } + } +} diff --git a/test/2239-varhandle-perf-vh-unsafe-put/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf-vh-unsafe-put/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf-vh-unsafe-put/src/UnsafeMicroBenchmark.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import jdk.internal.misc.Unsafe; + +class UnsafeMicroBenchmark extends MicroBenchmark { + protected Unsafe theUnsafe; + + UnsafeMicroBenchmark() throws Throwable { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + theUnsafe = (Unsafe) f.get(null); + } + + protected long getFieldOffset(Field field) throws Throwable { + return theUnsafe.objectFieldOffset(field); + } + + protected long getStaticFieldOffset(Field staticField) throws Throwable { + if (System.getProperty("java.vm.name").equals("Dalvik")) { + // field.getOffset(); ()J + Method m = Field.class.getDeclaredMethod("getOffset"); + return (Integer) m.invoke(staticField); + } else { + // theUnsafe.staticFieldOffset(field) (Ljava/lang/Field;)J + Method m = Unsafe.class.getDeclaredMethod("staticFieldOffset", Field.class); + return (Long) m.invoke(theUnsafe, staticField); + } + } +}
\ No newline at end of file diff --git a/test/knownfailures.json b/test/knownfailures.json index 688a2d3aa3..4b86df1cfd 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -1461,7 +1461,23 @@ { "tests": ["2235-JdkUnsafeTest", "2236-JdkUnsafeGetLong-regression", - "2239-varhandle-perf"], + "2239-varhandle-perf-vh-cae", + "2239-varhandle-perf-vh-cas", + "2239-varhandle-perf-vh-cas-weak", + "2239-varhandle-perf-vh-gaa", + "2239-varhandle-perf-vh-gab", + "2239-varhandle-perf-vh-gas", + "2239-varhandle-perf-vh-get", + "2239-varhandle-perf-vh-get-a", + "2239-varhandle-perf-vh-get-bav", + "2239-varhandle-perf-vh-reflect-get", + "2239-varhandle-perf-vh-reflect-set", + "2239-varhandle-perf-vh-set", + "2239-varhandle-perf-vh-set-a", + "2239-varhandle-perf-vh-set-bav", + "2239-varhandle-perf-vh-unsafe-cas", + "2239-varhandle-perf-vh-unsafe-get", + "2239-varhandle-perf-vh-unsafe-put"], "variant": "jvm", "bug": "b/195387473", "description": ["Depends on using language level 11."] @@ -1583,7 +1599,23 @@ "989-method-trace-throw", "2029-contended-monitors", "2043-reference-pauses", - "2239-varhandle-perf"], + "2239-varhandle-perf-vh-cae", + "2239-varhandle-perf-vh-cas", + "2239-varhandle-perf-vh-cas-weak", + "2239-varhandle-perf-vh-gaa", + "2239-varhandle-perf-vh-gab", + "2239-varhandle-perf-vh-gas", + "2239-varhandle-perf-vh-get", + "2239-varhandle-perf-vh-get-a", + "2239-varhandle-perf-vh-get-bav", + "2239-varhandle-perf-vh-reflect-get", + "2239-varhandle-perf-vh-reflect-set", + "2239-varhandle-perf-vh-set", + "2239-varhandle-perf-vh-set-a", + "2239-varhandle-perf-vh-set-bav", + "2239-varhandle-perf-vh-unsafe-cas", + "2239-varhandle-perf-vh-unsafe-get", + "2239-varhandle-perf-vh-unsafe-put"], "bug": "b/328023607", "description": ["Fails on QEMU"], "env_vars": {"ART_TEST_ON_VM": "true"} diff --git a/test/2239-varhandle-perf/util-src/generate_java.py b/test/utils/python/generate_java_varhandle_perf.py index 4c58c32501..e911800d5d 100644 --- a/test/2239-varhandle-perf/util-src/generate_java.py +++ b/test/utils/python/generate_java_varhandle_perf.py @@ -15,7 +15,7 @@ # limitations under the License. """ -Generate java benchmarks for 2238-varhandle-perf +Generate java benchmarks for 2239-varhandle-perf """ # TODO: fix constants when converting the test to a Golem benchmark @@ -397,92 +397,105 @@ UNSAFE_CAS = UNSAFE_START + """ theUnsafe.{method}({this_comma}offset, {value1}, {value2}); theUnsafe.{method}({this_comma}offset, {value2}, {value1});""" * REPEAT_HALF + END - -ALL_BENCHMARKS = ( - [BenchVHField(VH_GET, static, vartype, flavour, "get") - for flavour in ["", "Acquire", "Opaque", "Volatile"] - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchVHField(VH_SET, static, vartype, flavour, "set") - for flavour in ["", "Volatile", "Opaque", "Release"] - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchVHField(VH_CAS, static, vartype, flavour, "compareAndSet") - for flavour in [""] - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchVHField(VH_CAS, static, vartype, flavour, "weakCompareAndSet") - for flavour in ["", "Plain", "Acquire", "Release"] - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchVHField(VH_CAE, static, vartype, flavour, "compareAndExchange") - for flavour in ["", "Acquire", "Release"] - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchVHField(VH_GAS, static, vartype, flavour, "getAndSet") - for flavour in ["", "Acquire", "Release"] - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchVHField(VH_GAA, static, vartype, flavour, "getAndAdd") - for flavour in ["", "Acquire", "Release"] - for static in [True, False] - for vartype in ["int", "float"]] + - [BenchVHField(VH_GAB, static, vartype, flavour, "getAndBitwise") - for flavour in [oper + mode - for oper in ["Or", "Xor", "And"] - for mode in ["", "Acquire", "Release"]] - for static in [True, False] - for vartype in ["int"]] + - [BenchVHArray(VH_GET_A, vartype, flavour, "get") - for flavour in [""] - for vartype in ["int", "String"]] + - [BenchVHArray(VH_SET_A, vartype, flavour, "set") - for flavour in [""] - for vartype in ["int", "String"]] + - [BenchVHByteArrayView(VH_GET_BAV, byteorder, vartype, flavour, "get") - for flavour in [""] - for byteorder in ["BIG_ENDIAN", "LITTLE_ENDIAN"] - for vartype in ["int"]] + - [BenchVHByteArrayView(VH_SET_BAV, byteorder, vartype, flavour, "set") - for flavour in [""] - for byteorder in ["BIG_ENDIAN", "LITTLE_ENDIAN"] - for vartype in ["int"]] + - [BenchReflect(REFLECT_GET, static, vartype, "get") - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchReflect(REFLECT_SET, static, vartype, "set") - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchUnsafe(UNSAFE_GET, static, vartype, "get") - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchUnsafe(UNSAFE_PUT, static, vartype, "put") - for static in [True, False] - for vartype in ["int", "String"]] + - [BenchUnsafe(UNSAFE_CAS, static, vartype, method) - for method in ["compareAndSwap", "compareAndSet"] - for static in [True, False] - for vartype in ["int", "String"]]) - - -MAIN = BANNER + """ -public class Main { - static MicroBenchmark[] benchmarks; - - private static void initialize() throws Throwable { - benchmarks = new MicroBenchmark[] {""" + "".join([""" - new {}(),""".format(b.fullname()) for b in ALL_BENCHMARKS]) + """ - }; - } - - public static void main(String[] args) throws Throwable { - initialize(); - for (MicroBenchmark benchmark : benchmarks) { - benchmark.report(); - } - } -}""" - +def benchmark_selector(benchmark_to_run): + if benchmark_to_run == '0': + return ( + [BenchVHField(VH_GET, static, vartype, flavour, "get") + for flavour in ["", "Acquire", "Opaque", "Volatile"] + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '1': + return ( + [BenchVHField(VH_SET, static, vartype, flavour, "set") + for flavour in ["", "Volatile", "Opaque", "Release"] + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '2': + return ( + [BenchVHField(VH_CAS, static, vartype, flavour, "compareAndSet") + for flavour in [""] + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '3': + return ( + [BenchVHField(VH_CAS, static, vartype, flavour, "weakCompareAndSet") + for flavour in ["", "Plain", "Acquire", "Release"] + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '4': + return ( + [BenchVHField(VH_CAE, static, vartype, flavour, "compareAndExchange") + for flavour in ["", "Acquire", "Release"] + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '5': + return ( + [BenchVHField(VH_GAS, static, vartype, flavour, "getAndSet") + for flavour in ["", "Acquire", "Release"] + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '6': + return ( + [BenchVHField(VH_GAA, static, vartype, flavour, "getAndAdd") + for flavour in ["", "Acquire", "Release"] + for static in [True, False] + for vartype in ["int", "float"]]) + elif benchmark_to_run == '7': + return ( + [BenchVHField(VH_GAB, static, vartype, flavour, "getAndBitwise") + for flavour in [oper + mode + for oper in ["Or", "Xor", "And"] + for mode in ["", "Acquire", "Release"]] + for static in [True, False] + for vartype in ["int"]]) + elif benchmark_to_run == '8': + return ( + [BenchVHArray(VH_GET_A, vartype, flavour, "get") + for flavour in [""] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '9': + return ( + [BenchVHArray(VH_SET_A, vartype, flavour, "set") + for flavour in [""] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '10': + return ( + [BenchVHByteArrayView(VH_GET_BAV, byteorder, vartype, flavour, "get") + for flavour in [""] + for byteorder in ["BIG_ENDIAN", "LITTLE_ENDIAN"] + for vartype in ["int"]]) + elif benchmark_to_run == '11': + return ( + [BenchVHByteArrayView(VH_SET_BAV, byteorder, vartype, flavour, "set") + for flavour in [""] + for byteorder in ["BIG_ENDIAN", "LITTLE_ENDIAN"] + for vartype in ["int"]]) + elif benchmark_to_run == '12': + return ( + [BenchReflect(REFLECT_GET, static, vartype, "get") + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '13': + return ( + [BenchReflect(REFLECT_SET, static, vartype, "set") + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '14': + return ( + [BenchUnsafe(UNSAFE_GET, static, vartype, "get") + for static in [True, False] + for vartype in ["int", "String"]]) + elif benchmark_to_run == '15': + return ( + [BenchUnsafe(UNSAFE_PUT, static, vartype, "put") + for static in [True, False] + for vartype in ["int", "String"]]) + else: + return ( + [BenchUnsafe(UNSAFE_CAS, static, vartype, method) + for method in ["compareAndSwap", "compareAndSet"] + for static in [True, False] + for vartype in ["int", "String"]]) def main(argv): final_java_dir = Path(argv[1]) @@ -490,6 +503,27 @@ def main(argv): print("{} is not a valid java dir".format(final_java_dir), file=sys.stderr) sys.exit(1) + benchmark_to_run = argv[2] + ALL_BENCHMARKS = benchmark_selector(benchmark_to_run) + + MAIN = BANNER + """ + public class Main { + static MicroBenchmark[] benchmarks; + + private static void initialize() throws Throwable { + benchmarks = new MicroBenchmark[] {""" + "".join([""" + new {}(),""".format(b.fullname()) for b in ALL_BENCHMARKS]) + """ + }; + } + + public static void main(String[] args) throws Throwable { + initialize(); + for (MicroBenchmark benchmark : benchmarks) { + benchmark.report(); + } + } + }""" + for bench in ALL_BENCHMARKS: file_path = final_java_dir / "{}.java".format(bench.fullname()) with file_path.open("w") as f: diff --git a/tools/fuzzer/Android.bp b/tools/fuzzer/Android.bp index 4042250476..f885ccb654 100644 --- a/tools/fuzzer/Android.bp +++ b/tools/fuzzer/Android.bp @@ -628,7 +628,23 @@ genrule { "host_2237-checker-inline-multidex_classes.dex", "host_2237-checker-inline-multidex_classes2.dex", "host_2238-checker-polymorphic-recursive-inlining_classes.dex", - "host_2239-varhandle-perf_classes.dex", + "host_2239-varhandle-perf-vh-cae_classes.dex", + "host_2239-varhandle-perf-vh-cas_classes.dex", + "host_2239-varhandle-perf-vh-cas-weak_classes.dex", + "host_2239-varhandle-perf-vh-gaa_classes.dex", + "host_2239-varhandle-perf-vh-gab_classes.dex", + "host_2239-varhandle-perf-vh-gas_classes.dex", + "host_2239-varhandle-perf-vh-get_classes.dex", + "host_2239-varhandle-perf-vh-get-a_classes.dex", + "host_2239-varhandle-perf-vh-get-bav_classes.dex", + "host_2239-varhandle-perf-vh-reflect-get_classes.dex", + "host_2239-varhandle-perf-vh-reflect-set_classes.dex", + "host_2239-varhandle-perf-vh-set_classes.dex", + "host_2239-varhandle-perf-vh-set-a_classes.dex", + "host_2239-varhandle-perf-vh-set-bav_classes.dex", + "host_2239-varhandle-perf-vh-unsafe-cas_classes.dex", + "host_2239-varhandle-perf-vh-unsafe-get_classes.dex", + "host_2239-varhandle-perf-vh-unsafe-put_classes.dex", "host_2240-tracing-non-invokable-method_classes.dex", "host_2241-checker-inline-try-catch_classes.dex", "host_2242-checker-lse-acquire-release-operations_classes.dex", |