ART: Skip duplicate classes during compilation

If a class doesn't resolve to the current dex file, processing can be
skipped. It must have been handled before.

For a large test app, compiling with -j1, compile phase only:

          Before    After
Quicken   14.270   13.541
Speed    156.621  153.591

Bug: 78201536
Test: m test-art-host
Change-Id: Ia5df3f7f6da2be114a5e9051c18d5716a5f48515
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 41b7e7b..723c619 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2160,6 +2160,9 @@
         DCHECK(failure_kind == verifier::FailureKind::kNoFailure) << failure_kind;
         failure_kind = verifier::FailureKind::kSoftFailure;
       }
+    } else if (&klass->GetDexFile() != &dex_file) {
+      // Skip a duplicate class (as the resolved class is from another, earlier dex file).
+      return;  // Do not update state.
     } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
       CHECK(klass->IsResolved()) << klass->PrettyClass();
       failure_kind = class_linker->VerifyClass(soa.Self(), klass, log_level_);
@@ -2804,6 +2807,9 @@
       dex_cache = hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file));
     } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
       return;
+    } else if (&klass->GetDexFile() != &dex_file) {
+      // Skip a duplicate class (as the resolved class is from another, earlier dex file).
+      return;  // Do not update state.
     } else {
       dex_cache = hs.NewHandle(klass->GetDexCache());
     }
diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc
index 553d131..06f0bcd 100644
--- a/compiler/verifier_deps_test.cc
+++ b/compiler/verifier_deps_test.cc
@@ -236,6 +236,8 @@
         if (cls == nullptr) {
           CHECK(soa.Self()->IsExceptionPending());
           soa.Self()->ClearException();
+        } else if (&cls->GetDexFile() != dex_file) {
+          // Ignore classes from different dex files.
         } else if (unverified_classes.find(class_def.class_idx_) == unverified_classes.end()) {
           ASSERT_EQ(cls->GetStatus(), ClassStatus::kVerified);
         } else {