Don't analyze methods with verification errors.

With regression test!

Bug: 72874888

Test: test-art-host

Change-Id: Icb3ec5dbfa14a1f77da681ba7e100ec9a5ab9ba6
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 6144162..bbf8c26 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -445,6 +445,9 @@
         ? GetGraph()->GetDexFile().PrettyMethod(invoke->GetDexMethodIndex(), kWithSignature)
         : method->PrettyMethod(kWithSignature);
     StartAttributeStream("method_name") << method_name;
+    StartAttributeStream("always_throws") << std::boolalpha
+                                          << invoke->AlwaysThrows()
+                                          << std::noboolalpha;
   }
 
   void VisitInvokeUnresolved(HInvokeUnresolved* invoke) OVERRIDE {
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 035e5ce..b9ae0ff 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -392,10 +392,33 @@
   return single_impl;
 }
 
-static bool AlwaysThrows(ArtMethod* method)
+static bool IsMethodUnverified(CompilerDriver* const compiler_driver, ArtMethod* method)
     REQUIRES_SHARED(Locks::mutator_lock_) {
-  CodeItemDataAccessor accessor(method->DexInstructionData());
+  if (!method->GetDeclaringClass()->IsVerified()) {
+    if (Runtime::Current()->UseJitCompilation()) {
+      // We're at runtime, we know this is cold code if the class
+      // is not verified, so don't bother analyzing.
+      return true;
+    }
+    uint16_t class_def_idx = method->GetDeclaringClass()->GetDexClassDefIndex();
+    if (!compiler_driver->IsMethodVerifiedWithoutFailures(
+        method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) {
+      // Method has soft or hard failures, don't analyze.
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool AlwaysThrows(CompilerDriver* const compiler_driver, ArtMethod* method)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  DCHECK(method != nullptr);
+  // Skip non-compilable and unverified methods.
+  if (!method->IsCompilable() || IsMethodUnverified(compiler_driver, method)) {
+    return false;
+  }
   // Skip native methods, methods with try blocks, and methods that are too large.
+  CodeItemDataAccessor accessor(method->DexInstructionData());
   if (!accessor.HasCodeItem() ||
       accessor.TriesSize() != 0 ||
       accessor.InsnsSizeInCodeUnits() > kMaximumNumberOfTotalInstructions) {
@@ -478,7 +501,7 @@
           MaybeRecordStat(stats_, MethodCompilationStat::kInlinedInvokeVirtualOrInterface);
         }
       }
-    } else if (!cha_devirtualize && AlwaysThrows(actual_method)) {
+    } else if (!cha_devirtualize && AlwaysThrows(compiler_driver_, actual_method)) {
       // Set always throws property for non-inlined method call with single target
       // (unless it was obtained through CHA, because that would imply we have
       // to add the CHA dependency, which seems not worth it).
@@ -1450,16 +1473,11 @@
         << " has soft failures un-handled by the compiler, so it cannot be inlined";
   }
 
-  if (!method->GetDeclaringClass()->IsVerified()) {
-    uint16_t class_def_idx = method->GetDeclaringClass()->GetDexClassDefIndex();
-    if (Runtime::Current()->UseJitCompilation() ||
-        !compiler_driver_->IsMethodVerifiedWithoutFailures(
-            method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) {
-      LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedNotVerified)
-          << "Method " << method->PrettyMethod()
-          << " couldn't be verified, so it cannot be inlined";
-      return false;
-    }
+  if (IsMethodUnverified(compiler_driver_, method)) {
+    LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedNotVerified)
+        << "Method " << method->PrettyMethod()
+        << " couldn't be verified, so it cannot be inlined";
+    return false;
   }
 
   if (invoke_instruction->IsInvokeStaticOrDirect() &&