diff options
| -rwxr-xr-x | test/2239-varhandle-perf/build | 32 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/check | 21 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/expected-stderr.txt | 0 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/expected-stdout.txt | 0 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/info.txt | 1 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/src/BenchmarkBase.java | 85 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/src/MicroBenchmark.java | 54 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/src/UnsafeMicroBenchmark.java | 45 | ||||
| -rw-r--r-- | test/2239-varhandle-perf/util-src/generate_java.py | 504 | ||||
| -rw-r--r-- | test/knownfailures.json | 3 | 
10 files changed, 744 insertions, 1 deletions
diff --git a/test/2239-varhandle-perf/build b/test/2239-varhandle-perf/build new file mode 100755 index 0000000000..115a0fba49 --- /dev/null +++ b/test/2239-varhandle-perf/build @@ -0,0 +1,32 @@ +#!/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 ./util-src/generate_java.py "${GENERATED_SRC}" + +./default-build "$@" --experimental var-handles diff --git a/test/2239-varhandle-perf/check b/test/2239-varhandle-perf/check new file mode 100644 index 0000000000..8ea102d53c --- /dev/null +++ b/test/2239-varhandle-perf/check @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Copyright 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. + +# Dump the output of the benchmarks that run and report success. The +# benchmarks ran successfully if we get as far as this script. + +cat "$2" +exit 0 diff --git a/test/2239-varhandle-perf/expected-stderr.txt b/test/2239-varhandle-perf/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf/expected-stderr.txt diff --git a/test/2239-varhandle-perf/expected-stdout.txt b/test/2239-varhandle-perf/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2239-varhandle-perf/expected-stdout.txt diff --git a/test/2239-varhandle-perf/info.txt b/test/2239-varhandle-perf/info.txt new file mode 100644 index 0000000000..943303dfaf --- /dev/null +++ b/test/2239-varhandle-perf/info.txt @@ -0,0 +1 @@ +Temporary benchmarks for VarHandle accessors and some alternatives. diff --git a/test/2239-varhandle-perf/src/BenchmarkBase.java b/test/2239-varhandle-perf/src/BenchmarkBase.java new file mode 100644 index 0000000000..ee390b46ad --- /dev/null +++ b/test/2239-varhandle-perf/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/src/MicroBenchmark.java b/test/2239-varhandle-perf/src/MicroBenchmark.java new file mode 100644 index 0000000000..bd72f58842 --- /dev/null +++ b/test/2239-varhandle-perf/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/src/UnsafeMicroBenchmark.java b/test/2239-varhandle-perf/src/UnsafeMicroBenchmark.java new file mode 100644 index 0000000000..1b8c0af959 --- /dev/null +++ b/test/2239-varhandle-perf/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/util-src/generate_java.py b/test/2239-varhandle-perf/util-src/generate_java.py new file mode 100644 index 0000000000..4c58c32501 --- /dev/null +++ b/test/2239-varhandle-perf/util-src/generate_java.py @@ -0,0 +1,504 @@ +#!/usr/bin/python3 +# +# 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. + +""" +Generate java benchmarks for 2238-varhandle-perf +""" +# TODO: fix constants when converting the test to a Golem benchmark + + +from enum import Enum +from pathlib import Path + +import io +import sys + + +class MemLoc(Enum): +    FIELD = 0 +    ARRAY = 1 +    BYTE_ARRAY_VIEW = 2 + + +def to_camel_case(word): +    return ''.join(c for c in word.title() if not c == '_') + + +class Benchmark: +    def __init__(self, code, static, vartype, flavour, klass, method, memloc, +        byteorder="LITTLE_ENDIAN"): +        self.code = code +        self.static = static +        self.vartype = vartype +        self.flavour = flavour +        self.klass = klass +        self.method = method +        self.byteorder = byteorder +        self.memloc = memloc + +    def fullname(self): +        return "{klass}{method}{flavour}{static_name}{memloc}{byteorder}{vartype}Benchmark".format( +            klass = self.klass, +            method = to_camel_case(self.method), +            flavour = self.flavour, +            static_name = "Static" if self.static else "", +            memloc = to_camel_case(self.memloc.name), +            byteorder = to_camel_case(self.byteorder), +            vartype = to_camel_case(self.vartype)) + +    def gencode(self): +        if self.klass == "Reflect": +            method_suffix = "" if self.vartype == "String" else self.vartype.title() +            static_first_arg = "null" +        elif self.klass == "Unsafe": +            method_suffix = "Object" if self.vartype == "String" else self.vartype.title() +            static_first_arg = "this.getClass()" +        else: +            method_suffix = "" +            static_first_arg = "" + +        first_arg = static_first_arg if self.static else "this" + +        return self.code.format( +            name = self.fullname(), +            method = self.method + method_suffix, +            flavour = self.flavour, +            static_name = "Static" if self.static else "", +            static_kwd = "static " if self.static else "", +            this = first_arg, +            this_comma = "" if not first_arg else first_arg + ", ", +            vartype = self.vartype, +            byteorder = self.byteorder, +            value1 = VALUES[self.vartype][0], +            value2 = VALUES[self.vartype][1], +            value1_byte_array = VALUES["byte[]"][self.byteorder][0], +            value2_byte_array = VALUES["byte[]"][self.byteorder][1], +            loop = "for (int pass = 0; pass < 100; ++pass)", +            iters = ITERATIONS) + + +def BenchVHField(code, static, vartype, flavour, method): +    return Benchmark(code, static, vartype, flavour, "VarHandle", method, MemLoc.FIELD) + + +def BenchVHArray(code, vartype, flavour, method): +    return Benchmark(code, False, vartype, flavour, "VarHandle", method, MemLoc.ARRAY) + + +def BenchVHByteArrayView(code, byteorder, vartype, flavour, method): +    return Benchmark(code, False, vartype, flavour, "VarHandle", method, MemLoc.BYTE_ARRAY_VIEW, byteorder) + + +def BenchReflect(code, static, vartype, method): +    return Benchmark(code, static, vartype, "", "Reflect", method, MemLoc.FIELD) + + +def BenchUnsafe(code, static, vartype, method): +    return Benchmark(code, static, vartype, "", "Unsafe", method, MemLoc.FIELD) + + +VALUES = { +    "int": ["42", "~42"], +    "float": ["3.14f", "2.17f"], +    "String": ["\"qwerty\"", "null"], +    "byte[]": { +        "LITTLE_ENDIAN": [ +            "{ (byte) VALUE, (byte) (VALUE >> 8), (byte) (VALUE >> 16), (byte) (VALUE >> 24) }", +            "{ (byte) VALUE, (byte) (-1 >> 8), (byte) (-1 >> 16), (byte) (-1 >> 24) }", +        ], +        "BIG_ENDIAN": [ +            "{ (byte) (VALUE >> 24), (byte) (VALUE >> 16), (byte) (VALUE >> 8), (byte) VALUE }", +            "{ (byte) (-1 >> 24), (byte) (-1 >> 16), (byte) (-1 >> 8), (byte) VALUE }", +        ], +    }, +} + + +# TODO: fix these numbers when converting the test to a Golem benchmark +ITERATIONS = 1 # 3000 for a real benchmark +REPEAT = 2 # 30 for a real benchmark +REPEAT_HALF = (int) (REPEAT / 2) + + +BANNER = '// This file is generated by util-src/generate_java.py do not directly modify!' + + +VH_IMPORTS = """ +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +""" + + +VH_START = BANNER + VH_IMPORTS + """ +class {name} extends MicroBenchmark {{ +  static final {vartype} FIELD_VALUE = {value1}; +  {static_kwd}{vartype} field = FIELD_VALUE; +  VarHandle vh; + +  {name}() throws Throwable {{ +    vh = MethodHandles.lookup().find{static_name}VarHandle(this.getClass(), "field", {vartype}.class); +  }} +""" + + +END = """ +    }} +  }} + +  @Override +  public int innerIterations() {{ +      return {iters}; +  }} +}}""" + + +VH_GET = VH_START + """ +  @Override +  public void setup() {{ +    {vartype} v = ({vartype}) vh.{method}{flavour}({this}); +    if (v != FIELD_VALUE) {{ +      throw new RuntimeException("field has unexpected value " + v); +    }} +  }} + +  @Override +  public void run() {{ +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}({this});""" * REPEAT + END + + +VH_SET = VH_START + """ +  @Override +  public void teardown() {{ +    if (field != FIELD_VALUE) {{ +      throw new RuntimeException("field has unexpected value " + field); +    }} +  }} + +  @Override +  public void run() {{ +    {vartype} x; +    {loop} {{""" + """ +      vh.{method}{flavour}({this_comma}FIELD_VALUE);""" * REPEAT + END + + +VH_CAS = VH_START + """ +  @Override +  public void run() {{ +    boolean success; +    {loop} {{""" + """ +      success = vh.{method}{flavour}({this_comma}field, {value2}); +      success = vh.{method}{flavour}({this_comma}field, {value1});""" * REPEAT_HALF + END + + +VH_CAE = VH_START + """ +  @Override +  public void run() {{ +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}({this_comma}field, {value2}); +      x = ({vartype}) vh.{method}{flavour}({this_comma}field, {value1});""" * REPEAT_HALF + END + + +VH_GAS = VH_START + """ +  @Override +  public void run() {{ +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}({this_comma}{value2});""" * REPEAT + END + + +VH_GAA = VH_START + """ +  @Override +  public void run() {{ +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}({this_comma}{value2});""" * REPEAT + END + + +VH_GAB = VH_START + """ +  @Override +  public void run() {{ +    int x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}({this_comma}{value2});""" * REPEAT + END + + +VH_START_ARRAY = BANNER + VH_IMPORTS + """ +class {name} extends MicroBenchmark {{ +  static final {vartype} ELEMENT_VALUE = {value1}; +  {vartype}[] array = {{ ELEMENT_VALUE }}; +  VarHandle vh; + +  {name}() throws Throwable {{ +    vh = MethodHandles.arrayElementVarHandle({vartype}[].class); +  }} +""" + + +VH_GET_A = VH_START_ARRAY + """ +  @Override +  public void setup() {{ +    {vartype} v = ({vartype}) vh.{method}{flavour}(array, 0); +    if (v != ELEMENT_VALUE) {{ +      throw new RuntimeException("array element has unexpected value: " + v); +    }} +  }} + +  @Override +  public void run() {{ +    {vartype}[] a = array; +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}(a, 0);""" * REPEAT + END + + +VH_SET_A = VH_START_ARRAY + """ +  @Override +  public void teardown() {{ +    if (array[0] != {value2}) {{ +      throw new RuntimeException("array element has unexpected value: " + array[0]); +    }} +  }} + +  @Override +  public void run() {{ +    {vartype}[] a = array; +    {vartype} x; +    {loop} {{""" + """ +      vh.{method}{flavour}(a, 0, {value2});""" * REPEAT + END + + +VH_START_BYTE_ARRAY_VIEW = BANNER + VH_IMPORTS + """ +import java.util.Arrays; +import java.nio.ByteOrder; + +class {name} extends MicroBenchmark {{ +  static final {vartype} VALUE = {value1}; +  byte[] array1 = {value1_byte_array}; +  byte[] array2 = {value2_byte_array}; +  VarHandle vh; + +  {name}() throws Throwable {{ +    vh = MethodHandles.byteArrayViewVarHandle({vartype}[].class, ByteOrder.{byteorder}); +  }} +""" + + +VH_GET_BAV = VH_START_BYTE_ARRAY_VIEW + """ +  @Override +  public void setup() {{ +    {vartype} v = ({vartype}) vh.{method}{flavour}(array1, 0); +    if (v != VALUE) {{ +      throw new RuntimeException("array has unexpected value: " + v); +    }} +  }} + +  @Override +  public void run() {{ +    byte[] a = array1; +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) vh.{method}{flavour}(a, 0);""" * REPEAT + END + + +VH_SET_BAV = VH_START_BYTE_ARRAY_VIEW + """ +  @Override +  public void teardown() {{ +    if (!Arrays.equals(array2, array1)) {{ +      throw new RuntimeException("array has unexpected values: " + +          array2[0] + " " + array2[1] + " " + array2[2] + " " + array2[3]); +    }} +  }} + +  @Override +  public void run() {{ +    byte[] a = array2; +    {loop} {{""" + """ +      vh.{method}{flavour}(a, 0, VALUE);""" * REPEAT + END + + +REFLECT_START = BANNER + """ +import java.lang.reflect.Field; + +class {name} extends MicroBenchmark {{ +  Field field; +  {static_kwd}{vartype} value; + +  {name}() throws Throwable {{ +    field = this.getClass().getDeclaredField("value"); +  }} +""" + + +REFLECT_GET = REFLECT_START + """ +  @Override +  public void run() throws Throwable {{ +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) field.{method}({this});""" * REPEAT + END + + +REFLECT_SET = REFLECT_START + """ +  @Override +  public void run() throws Throwable {{ +    {loop} {{""" + """ +      field.{method}({this_comma}{value1});""" * REPEAT + END + + +UNSAFE_START = BANNER + """ +import java.lang.reflect.Field; +import jdk.internal.misc.Unsafe; + +class {name} extends UnsafeMicroBenchmark {{ +  long offset; +  {static_kwd}{vartype} value = {value1}; + +  {name}() throws Throwable {{ +    Field field = this.getClass().getDeclaredField("value"); +    offset = get{static_name}FieldOffset(field); +  }} +""" + + +UNSAFE_GET = UNSAFE_START + """ +  @Override +  public void run() throws Throwable {{ +    {vartype} x; +    {loop} {{""" + """ +      x = ({vartype}) theUnsafe.{method}({this_comma}offset);""" * REPEAT + END + + +UNSAFE_PUT = UNSAFE_START + """ +  @Override +  public void run() throws Throwable {{ +    {loop} {{""" + """ +      theUnsafe.{method}({this_comma}offset, {value1});""" * REPEAT + END + + +UNSAFE_CAS = UNSAFE_START + """ +  @Override +  public void run() throws Throwable {{ +    {loop} {{""" + """ +      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 main(argv): +    final_java_dir = Path(argv[1]) +    if not final_java_dir.exists() or not final_java_dir.is_dir(): +        print("{} is not a valid java dir".format(final_java_dir), file=sys.stderr) +        sys.exit(1) + +    for bench in ALL_BENCHMARKS: +        file_path = final_java_dir / "{}.java".format(bench.fullname()) +        with file_path.open("w") as f: +            print(bench.gencode(), file=f) + +    file_path = final_java_dir / "Main.java" +    with file_path.open("w") as f: +        print(MAIN, file=f) + + +if __name__ == '__main__': +    main(sys.argv) diff --git a/test/knownfailures.json b/test/knownfailures.json index f8b069e41e..9750ba773b 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -1449,7 +1449,8 @@      },      {          "tests": ["2235-JdkUnsafeTest", -                  "2236-JdkUnsafeGetLong-regression"], +                  "2236-JdkUnsafeGetLong-regression", +                  "2239-varhandle-perf"],          "variant": "jvm",          "bug": "b/195387473",          "description": ["Depends on using language level 11."]  |