Fix issue with exception type resolution during linking.

When using default methods that cross dex-files we would sometimes
attempt to lookup method information using the wrong dex file. This
fixes this issue.

Bug: 26872564

Change-Id: I3c4b64ef970017356962060f3bd3781b4629a3c8
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index e98baba..5ef199c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3666,7 +3666,7 @@
     }
     self->AssertNoPendingException();
     // Make sure all classes referenced by catch blocks are resolved.
-    ResolveClassExceptionHandlerTypes(dex_file, klass);
+    ResolveClassExceptionHandlerTypes(klass);
     if (verifier_failure == verifier::MethodVerifier::kNoFailure) {
       // Even though there were no verifier failures we need to respect whether the super-class and
       // super-default-interfaces were verified or requiring runtime reverification.
@@ -3802,17 +3802,16 @@
   UNREACHABLE();
 }
 
-void ClassLinker::ResolveClassExceptionHandlerTypes(const DexFile& dex_file,
-                                                    Handle<mirror::Class> klass) {
+void ClassLinker::ResolveClassExceptionHandlerTypes(Handle<mirror::Class> klass) {
   for (ArtMethod& method : klass->GetMethods(image_pointer_size_)) {
-    ResolveMethodExceptionHandlerTypes(dex_file, &method);
+    ResolveMethodExceptionHandlerTypes(&method);
   }
 }
 
-void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file,
-                                                     ArtMethod* method) {
+void ClassLinker::ResolveMethodExceptionHandlerTypes(ArtMethod* method) {
   // similar to DexVerifier::ScanTryCatchBlocks and dex2oat's ResolveExceptionsForMethod.
-  const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset());
+  const DexFile::CodeItem* code_item =
+      method->GetDexFile()->GetCodeItem(method->GetCodeItemOffset());
   if (code_item == nullptr) {
     return;  // native or abstract method
   }
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 99dd073..5176cbd 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -441,11 +441,10 @@
                                mirror::Class::Status& oat_file_class_status)
       SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(!dex_lock_);
-  void ResolveClassExceptionHandlerTypes(const DexFile& dex_file,
-                                         Handle<mirror::Class> klass)
+  void ResolveClassExceptionHandlerTypes(Handle<mirror::Class> klass)
       SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(!dex_lock_);
-  void ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, ArtMethod* klass)
+  void ResolveMethodExceptionHandlerTypes(ArtMethod* klass)
       SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(!dex_lock_);
 
diff --git a/test/973-default-multidex/expected.txt b/test/973-default-multidex/expected.txt
new file mode 100644
index 0000000..b376e81
--- /dev/null
+++ b/test/973-default-multidex/expected.txt
@@ -0,0 +1 @@
+STRING!!!STRING!!!
diff --git a/test/973-default-multidex/info.txt b/test/973-default-multidex/info.txt
new file mode 100644
index 0000000..17c0b7d
--- /dev/null
+++ b/test/973-default-multidex/info.txt
@@ -0,0 +1,5 @@
+Smali-based tests for interface default methods.
+
+Obviously needs to run under ART or a Java 8 Language runtime and compiler.
+
+Tests that we handle referenced throws across dex files.
diff --git a/test/973-default-multidex/smali-multidex/iface.smali b/test/973-default-multidex/smali-multidex/iface.smali
new file mode 100644
index 0000000..fa6d27f
--- /dev/null
+++ b/test/973-default-multidex/smali-multidex/iface.smali
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 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.
+
+
+.class public abstract interface LIface;
+.super Ljava/lang/Object;
+
+# public interface Iface {
+#     public default String getTwice() {
+#         return getString() + getString();
+#     }
+#     public String getString();
+# }
+
+.method public getTwice()Ljava/lang/String;
+.locals 2
+    invoke-static {p0}, Ljava/util/Objects;->requireNonNull(Ljava/lang/Object;)Ljava/lang/Object;
+    invoke-interface {p0}, LIface;->getString()Ljava/lang/String;
+    move-result-object v0
+    invoke-interface {p0}, LIface;->getString()Ljava/lang/String;
+    move-result-object v1
+    invoke-virtual {v0, v1}, Ljava/lang/String;->concat(Ljava/lang/String;)Ljava/lang/String;
+    move-result-object v0
+    return-object v0
+.end method
+
+.method public abstract getString()Ljava/lang/String;
+.end method
diff --git a/test/973-default-multidex/smali/concreteclass.smali b/test/973-default-multidex/smali/concreteclass.smali
new file mode 100644
index 0000000..e177f26
--- /dev/null
+++ b/test/973-default-multidex/smali/concreteclass.smali
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 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.
+
+
+.class public LConcreteClass;
+.super Ljava/lang/Object;
+.implements LIface;
+
+# public class ConcreteClass implements Iface {
+#     public String getString() {
+#         return "STRING!!!";
+#     }
+#     public String callMethod() {
+#         return this.getTwice();
+#     }
+# }
+
+.method public constructor <init>()V
+    .registers 1
+    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+    return-void
+.end method
+
+.method public getString()Ljava/lang/String;
+.registers 2
+    const-string v0, "STRING!!!"
+    return-object v0
+.end method
+
+.method public callMethod()Ljava/lang/String;
+.registers 2
+    invoke-virtual {p0}, LConcreteClass;->getTwice()Ljava/lang/String;
+    move-result-object v0
+    return-object v0
+.end method
diff --git a/test/973-default-multidex/src/Main.java b/test/973-default-multidex/src/Main.java
new file mode 100644
index 0000000..b93265a
--- /dev/null
+++ b/test/973-default-multidex/src/Main.java
@@ -0,0 +1,31 @@
+/*
+ * 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 java.lang.reflect.*;
+public class Main {
+  public static void main(String[] args) {
+    Class<?> c = null;
+    try {
+      c = Class.forName("ConcreteClass");
+      Method m = c.getMethod("callMethod");
+      System.out.println(m.invoke(c.newInstance(), new Object[0]));
+    } catch (Exception e) {
+      e.printStackTrace();
+      System.out.println("FAILED: Could not call method");
+      return;
+    }
+  }
+}