diff options
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 10 | ||||
-rw-r--r-- | test/133-static-invoke-super/expected.txt | 3 | ||||
-rw-r--r-- | test/133-static-invoke-super/info.txt | 2 | ||||
-rwxr-xr-x | test/133-static-invoke-super/run | 18 | ||||
-rw-r--r-- | test/133-static-invoke-super/src/Main.java | 63 | ||||
-rw-r--r-- | test/Android.run-test.mk | 3 |
6 files changed, 98 insertions, 1 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 8ab90eb..a67ebca 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -930,6 +930,16 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, (caller->GetDexCacheResolvedMethod(update_dex_cache_method_index) != called)) { caller->SetDexCacheResolvedMethod(update_dex_cache_method_index, called); } + } else if (invoke_type == kStatic) { + const auto called_dex_method_idx = called->GetDexMethodIndex(); + // For static invokes, we may dispatch to the static method in the superclass but resolve + // using the subclass. To prevent getting slow paths on each invoke, we force set the + // resolved method for the super class dex method index if we are in the same dex file. + // b/19175856 + if (called->GetDexFile() == called_method.dex_file && + called_method.dex_method_index != called_dex_method_idx) { + called->GetDexCache()->SetResolvedMethod(called_dex_method_idx, called); + } } // Ensure that the called method's class is initialized. StackHandleScope<1> hs(soa.Self()); diff --git a/test/133-static-invoke-super/expected.txt b/test/133-static-invoke-super/expected.txt new file mode 100644 index 0000000..089d8e8 --- /dev/null +++ b/test/133-static-invoke-super/expected.txt @@ -0,0 +1,3 @@ +basis: performed 50000000 iterations +test1: performed 50000000 iterations +Timing is acceptable. diff --git a/test/133-static-invoke-super/info.txt b/test/133-static-invoke-super/info.txt new file mode 100644 index 0000000..606331b --- /dev/null +++ b/test/133-static-invoke-super/info.txt @@ -0,0 +1,2 @@ +This is a performance test of invoking static methods in super class. To see the numbers, invoke +this test with the "--timing" option. diff --git a/test/133-static-invoke-super/run b/test/133-static-invoke-super/run new file mode 100755 index 0000000..e27a622 --- /dev/null +++ b/test/133-static-invoke-super/run @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright (C) 2012 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. + +# As this is a performance test we always use the non-debug build. +exec ${RUN} "${@/#libartd.so/libart.so}" diff --git a/test/133-static-invoke-super/src/Main.java b/test/133-static-invoke-super/src/Main.java new file mode 100644 index 0000000..7cfd099 --- /dev/null +++ b/test/133-static-invoke-super/src/Main.java @@ -0,0 +1,63 @@ + +public class Main { + static class SuperClass { + protected static int getVar(int w) { + return w & 0xF; + } + } + static class SubClass extends SuperClass { + final int getVarDirect(int w) { + return w & 0xF; + } + public void testDirect(int max) { + for (int i = 0; i < max; ++i) { + getVarDirect(max); + } + } + public void testStatic(int max) { + for (int i = 0; i < max; ++i) { + getVar(max); + } + } + } + + static public void main(String[] args) throws Exception { + boolean timing = (args.length >= 1) && args[0].equals("--timing"); + run(timing); + } + + static int testBasis(int interations) { + (new SubClass()).testDirect(interations); + return interations; + } + + static int testStatic(int interations) { + (new SubClass()).testStatic(interations); + return interations; + } + + static public void run(boolean timing) { + long time0 = System.nanoTime(); + int count1 = testBasis(50000000); + long time1 = System.nanoTime(); + int count2 = testStatic(50000000); + long time2 = System.nanoTime(); + + System.out.println("basis: performed " + count1 + " iterations"); + System.out.println("test1: performed " + count2 + " iterations"); + + double basisMsec = (time1 - time0) / (double) count1 / 1000000; + double msec1 = (time2 - time1) / (double) count2 / 1000000; + + if (msec1 < basisMsec * 5) { + System.out.println("Timing is acceptable."); + } else { + System.out.println("Iterations are taking too long!"); + timing = true; + } + if (timing) { + System.out.printf("basis time: %.3g msec\n", basisMsec); + System.out.printf("test1: %.3g msec per iteration\n", msec1); + } + } +} diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index b1e969d..2057cb9 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -166,7 +166,8 @@ endef # name-to-var # Tests that are timing sensitive and flaky on heavily loaded systems. TEST_ART_TIMING_SENSITIVE_RUN_TESTS := \ 053-wait-some \ - 055-enum-performance + 055-enum-performance \ + 133-static-invoke-super # disable timing sensitive tests on "dist" builds. ifdef dist_goal |