summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc10
-rw-r--r--test/133-static-invoke-super/expected.txt3
-rw-r--r--test/133-static-invoke-super/info.txt2
-rwxr-xr-xtest/133-static-invoke-super/run18
-rw-r--r--test/133-static-invoke-super/src/Main.java63
-rw-r--r--test/Android.run-test.mk3
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