| # |
| # Copyright 2016 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 sys |
| |
| max_conflict_depth = 20 # In practice does not go above 20 for reasonable IMT sizes |
| try: |
| imt_size = int(sys.argv[1]) |
| except (IndexError, ValueError): |
| print("Usage: python ImtConflictBenchmarkGen.py <IMT_SIZE>") |
| sys.exit(1) |
| |
| license = """\ |
| /* |
| * Copyright 2016 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. |
| */ |
| """ |
| description = """ |
| /** |
| * This file is script-generated by ImtConflictBenchmarkGen.py. |
| * It measures the performance impact of conflicts in interface method tables. |
| * Run `python ImtConflictBenchmarkGen.py > ImtConflictBenchmark.java` to regenerate. |
| * |
| * Each interface has 64 methods, which is the current size of an IMT. C0 implements |
| * one interface, C1 implements two, C2 implements three, and so on. The intent |
| * is that C0 has no conflicts in its IMT, C1 has depth-2 conflicts in |
| * its IMT, C2 has depth-3 conflicts, etc. This is currently guaranteed by |
| * the fact that we hash interface methods by taking their method index modulo 64. |
| * (Note that a "conflict depth" of 1 means no conflict at all.) |
| */\ |
| """ |
| |
| print(license) |
| print("package benchmarks;") |
| print("import com.google.caliper.BeforeExperiment;") |
| print(description) |
| |
| print("public class ImtConflictBenchmark {") |
| |
| # Warm up interface method tables |
| print(" @BeforeExperiment") |
| print(" public void setup() {") |
| for i in xrange(max_conflict_depth): |
| print(" C{0} c{0} = new C{0}();".format(i)) |
| for j in xrange(i+1): |
| print(" callF{}(c{});".format(imt_size * j, i)) |
| print(" }") |
| |
| # Print test cases--one for each conflict depth |
| for i in xrange(max_conflict_depth): |
| print(" public void timeConflictDepth{:02d}(int nreps) {{".format(i+1)) |
| print(" C{0} c{0} = new C{0}();".format(i)) |
| print(" for (int i = 0; i < nreps; i++) {") |
| # Cycle through each interface method in an IMT entry in order |
| # to test all conflict resolution possibilities |
| for j in xrange(max_conflict_depth): |
| print(" callF{}(c{});".format(imt_size * (j % (i + 1)), i)) |
| print(" }") |
| print(" }") |
| |
| # Make calls through the IMTs |
| for i in xrange(max_conflict_depth): |
| print(" public void callF{0}(I{1} i) {{ i.f{0}(); }}".format(imt_size*i, i)) |
| |
| # Class definitions, implementing varying amounts of interfaces |
| for i in xrange(max_conflict_depth): |
| interfaces = ", ".join(["I{}".format(j) for j in xrange(i+1)]) |
| print(" static class C{} implements {} {{}}".format(i, interfaces)) |
| |
| # Interface definitions, each with enough methods to fill an entire IMT |
| for i in xrange(max_conflict_depth): |
| print(" static interface I{} {{".format(i)) |
| for j in xrange(imt_size): |
| print(" default void f{}() {{}}".format(i*imt_size + j)) |
| print(" }") |
| |
| print "}" |