Another fix for the resolution trampoline and invokesuper.
We need to fully resolve the target method before updating the BSS.
Test: 811
Bug: 169047229
Change-Id: I2f3a6d60e3e44b00daea4af15c02b55e1c9098d6
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 45c50b0..39987c1 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1317,24 +1317,6 @@
DCHECK_EQ(caller->GetDexFile(), called_method.dex_file);
called = linker->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
self, called_method.index, caller, invoke_type);
-
- // If successful, update .bss entry in oat file if any.
- if (called != nullptr) {
- // We only put non copied methods in the BSS. Putting a copy can lead to an
- // odd situation where the ArtMethod being executed is unrelated to the
- // receiver of the method.
- called = called->GetCanonicalMethod();
- if (invoke_type == kSuper) {
- if (called->GetDexFile() == called_method.dex_file) {
- called_method.index = called->GetDexMethodIndex();
- } else {
- called_method.index = called->FindDexMethodIndexInOtherDexFile(
- *called_method.dex_file, called_method.index);
- DCHECK_NE(called_method.index, dex::kDexNoIndex);
- }
- }
- MaybeUpdateBssMethodEntry(called, called_method);
- }
}
const void* code = nullptr;
if (LIKELY(!self->IsExceptionPending())) {
@@ -1368,6 +1350,24 @@
<< mirror::Object::PrettyTypeOf(receiver) << " "
<< invoke_type << " " << orig_called->GetVtableIndex();
}
+ // Now that we know the actual target, update .bss entry in oat file, if
+ // any.
+ if (!called_method_known_on_entry) {
+ // We only put non copied methods in the BSS. Putting a copy can lead to an
+ // odd situation where the ArtMethod being executed is unrelated to the
+ // receiver of the method.
+ called = called->GetCanonicalMethod();
+ if (invoke_type == kSuper) {
+ if (called->GetDexFile() == called_method.dex_file) {
+ called_method.index = called->GetDexMethodIndex();
+ } else {
+ called_method.index = called->FindDexMethodIndexInOtherDexFile(
+ *called_method.dex_file, called_method.index);
+ DCHECK_NE(called_method.index, dex::kDexNoIndex);
+ }
+ }
+ MaybeUpdateBssMethodEntry(called, called_method);
+ }
// Static invokes need class initialization check but instance invokes can proceed even if
// the class is erroneous, i.e. in the edge case of escaping instances of erroneous classes.
diff --git a/test/811-checker-invoke-super-secondary/expected.txt b/test/811-checker-invoke-super-secondary/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/expected.txt
diff --git a/test/811-checker-invoke-super-secondary/info.txt b/test/811-checker-invoke-super-secondary/info.txt
new file mode 100644
index 0000000..1de0057
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/info.txt
@@ -0,0 +1,2 @@
+Regression test when a super call resolves to a method from a different class
+loader.
diff --git a/test/811-checker-invoke-super-secondary/smali-ex/OtherClass.smali b/test/811-checker-invoke-super-secondary/smali-ex/OtherClass.smali
new file mode 100644
index 0000000..ba58b9c
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/smali-ex/OtherClass.smali
@@ -0,0 +1,34 @@
+# 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.
+
+.class public LOtherClass;
+.super LOtherSuperClass;
+
+## CHECK-START: void OtherClass.$noinline$foo() register (after)
+## CHECK-DAG: InvokeStaticOrDirect dex_file_index:<<Index1:\d+>> method_name:SuperSuperClass.$noinline$foo
+## CHECK-DAG: InvokeStaticOrDirect dex_file_index:<<Index2:\d+>> method_name:SuperSuperClass.$noinline$foo
+## CHECK-EVAL: <<Index1>> == <<Index2>>
+.method public $noinline$foo()V
+.registers 1
+ invoke-super {p0}, LOtherSuperClass;->$noinline$foo()V
+ invoke-super {p0}, LSuperSuperClass;->$noinline$foo()V
+ return-void
+.end method
+
+.method public constructor <init>()V
+ .registers 1
+ invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+ return-void
+.end method
+
diff --git a/test/811-checker-invoke-super-secondary/smali-ex/OtherSuperClass.smali b/test/811-checker-invoke-super-secondary/smali-ex/OtherSuperClass.smali
new file mode 100644
index 0000000..4b444bb
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/smali-ex/OtherSuperClass.smali
@@ -0,0 +1,16 @@
+# 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.
+
+.class public LOtherSuperClass;
+.super LSuperClass;
diff --git a/test/811-checker-invoke-super-secondary/smali/SuperClass.smali b/test/811-checker-invoke-super-secondary/smali/SuperClass.smali
new file mode 100644
index 0000000..016da13
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/smali/SuperClass.smali
@@ -0,0 +1,16 @@
+# 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.
+
+.class public LSuperClass;
+.super LSuperSuperClass;
diff --git a/test/811-checker-invoke-super-secondary/smali/SuperSuperClass.smali b/test/811-checker-invoke-super-secondary/smali/SuperSuperClass.smali
new file mode 100644
index 0000000..4c4569e
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/smali/SuperSuperClass.smali
@@ -0,0 +1,21 @@
+# 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.
+
+.class public LSuperSuperClass;
+.super Ljava/lang/Object;
+
+.method public $noinline$foo()V
+.registers 1
+ return-void
+.end method
diff --git a/test/811-checker-invoke-super-secondary/src/Main.java b/test/811-checker-invoke-super-secondary/src/Main.java
new file mode 100644
index 0000000..6c9fcc1
--- /dev/null
+++ b/test/811-checker-invoke-super-secondary/src/Main.java
@@ -0,0 +1,34 @@
+/*
+ * 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 dalvik.system.PathClassLoader;
+
+class Main {
+ static final String TEST_NAME = "811-checker-invoke-super-secondary";
+
+ static final String DEX_FILE = System.getenv("DEX_LOCATION") + "/" + TEST_NAME + ".jar";
+
+ static final String SECONDARY_NAME = TEST_NAME + "-ex";
+ static final String SECONDARY_DEX_FILE =
+ System.getenv("DEX_LOCATION") + "/" + SECONDARY_NAME + ".jar";
+
+ public static void main(String[] args) throws Exception {
+ PathClassLoader pcl = new PathClassLoader(SECONDARY_DEX_FILE, Main.class.getClassLoader());
+
+ Class<?> secondaryCls = pcl.loadClass("OtherClass");
+ secondaryCls.getDeclaredMethod("$noinline$foo").invoke(secondaryCls.newInstance());
+ }
+}
diff --git a/test/knownfailures.json b/test/knownfailures.json
index f5a825c..1e0663d 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1134,6 +1134,7 @@
"808-checker-invoke-super",
"809-checker-invoke-super-bss",
"810-checker-invoke-super-default",
+ "811-checker-invoke-super-secondary",
"999-redefine-hiddenapi",
"1000-non-moving-space-stress",
"1001-app-image-regions",