Fix incompatible class change error for JIT stress mode

There was a problem with miranda methods, when we would dequicken to
one of these, it wouldn't resolve as virtual during the method
lowering resolve. The solution is to try resolving as interface if we
fail to resolve as virtual.

Fixed a bug in dequickening where unreachable register lines with
quick invokes would cause CHECK failuers. In this case we punt to the
interpreter (test 435-try-*).

Added test regression test. Example failure:
java.lang.IncompatibleClassChangeError: The method
'void Main$TheInterface.m()' was expected to be of type virtual but
instead was found to be of type interface (declaration of
'java.lang.reflect.ArtMethod' appears in
out/host/linux-x86/framework/core-libart-hostdex.jar)
  at Main.DoStuff(Main.java:37)
  at Main.main(Main.java:44)

Bug: 17950037

Change-Id: I39c32cc8849bf02032a4f61a7ce57462b7fcac75
diff --git a/compiler/dex/mir_method_info.cc b/compiler/dex/mir_method_info.cc
index 3d3d979..34fb1bf 100644
--- a/compiler/dex/mir_method_info.cc
+++ b/compiler/dex/mir_method_info.cc
@@ -58,8 +58,9 @@
   auto current_dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
   // Even if the referrer class is unresolved (i.e. we're compiling a method without class
   // definition) we still want to resolve methods and record all available info.
+  Runtime* const runtime = Runtime::Current();
   const DexFile* const dex_file = mUnit->GetDexFile();
-  const bool use_jit = Runtime::Current()->UseJit();
+  const bool use_jit = runtime->UseJit();
   const VerifiedMethod* const verified_method = mUnit->GetVerifiedMethod();
 
   for (auto it = method_infos, end = method_infos + count; it != end; ++it) {
@@ -80,7 +81,7 @@
       it->target_method_idx_ = it->MethodIndex();
       current_dex_cache.Assign(dex_cache.Get());
       resolved_method = compiler_driver->ResolveMethod(soa, dex_cache, class_loader, mUnit,
-                                                       it->MethodIndex(), invoke_type);
+                                                       it->target_method_idx_, invoke_type, true);
     } else {
       // The method index is actually the dex PC in this case.
       // Calculate the proper dex file and target method idx.
@@ -89,8 +90,7 @@
       // Don't devirt if we are in a different dex file since we can't have direct invokes in
       // another dex file unless we always put a direct / patch pointer.
       devirt_target = nullptr;
-      current_dex_cache.Assign(
-          Runtime::Current()->GetClassLinker()->FindDexCache(*it->target_dex_file_));
+      current_dex_cache.Assign(runtime->GetClassLinker()->FindDexCache(*it->target_dex_file_));
       CHECK(current_dex_cache.Get() != nullptr);
       DexCompilationUnit cu(
           mUnit->GetCompilationUnit(), mUnit->GetClassLoader(), mUnit->GetClassLinker(),
@@ -99,6 +99,14 @@
           nullptr /* verified_method not used */);
       resolved_method = compiler_driver->ResolveMethod(soa, current_dex_cache, class_loader, &cu,
                                                        it->target_method_idx_, invoke_type, false);
+      if (resolved_method == nullptr) {
+        // If the method is null then it should be a miranda method, in this case try
+        // re-loading it, this time as an interface method. The actual miranda method is in the
+        // vtable, but it will resolve to an interface method.
+        resolved_method = compiler_driver->ResolveMethod(
+            soa, current_dex_cache, class_loader, &cu, it->target_method_idx_, kInterface, false);
+        CHECK(resolved_method != nullptr);
+      }
       if (resolved_method != nullptr) {
         // Since this was a dequickened virtual, it is guaranteed to be resolved. However, it may be
         // resolved to an interface method. If this is the case then change the invoke type to
@@ -123,10 +131,9 @@
       it->vtable_idx_ =
           compiler_driver->GetResolvedMethodVTableIndex(resolved_method, invoke_type);
     }
-
     MethodReference target_method(it->target_dex_file_, it->target_method_idx_);
     int fast_path_flags = compiler_driver->IsFastInvoke(
-        soa, dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method,
+        soa, current_dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method,
         &invoke_type, &target_method, devirt_target, &it->direct_code_, &it->direct_method_);
     const bool is_referrers_class = referrer_class.Get() == resolved_method->GetDeclaringClass();
     const bool is_class_initialized =