Add verify-profile compiler filter

Only verifies and dex2dex compiles classes in the profile. Goal
is to reduce application launch time.

~2x faster than interpret-only for Facebook.

Bug: 27688727

(cherry picked from commit a079e3aa62cceb76c1c1811e6e09bcaf75e20289)

Change-Id: Iad5aa1adee3aa6c2408820e8cbbab2d4412021b8
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index cd9d80f..ea16cb2 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -383,6 +383,9 @@
 
   compiler_->Init();
 
+  if (compiler_options->VerifyOnlyProfile()) {
+    CHECK(profile_compilation_info_ != nullptr) << "Requires profile";
+  }
   if (boot_image_) {
     CHECK(image_classes_.get() != nullptr) << "Expected image classes for boot image";
   }
@@ -830,10 +833,12 @@
 
   const bool verification_enabled = compiler_options_->IsVerificationEnabled();
   const bool never_verify = compiler_options_->NeverVerify();
+  const bool verify_only_profile = compiler_options_->VerifyOnlyProfile();
 
   // We need to resolve for never_verify since it needs to run dex to dex to add the
   // RETURN_VOID_NO_BARRIER.
-  if (never_verify || verification_enabled) {
+  // Let the verifier resolve as needed for the verify_only_profile case.
+  if ((never_verify || verification_enabled) && !verify_only_profile) {
     Resolve(class_loader, dex_files, timings);
     VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
   }
@@ -918,6 +923,22 @@
   return result;
 }
 
+bool CompilerDriver::ShouldVerifyClassBasedOnProfile(const DexFile& dex_file,
+                                                     uint16_t class_idx) const {
+  if (!compiler_options_->VerifyOnlyProfile()) {
+    // No profile, verify everything.
+    return true;
+  }
+  DCHECK(profile_compilation_info_ != nullptr);
+  bool result = profile_compilation_info_->ContainsClass(dex_file, class_idx);
+  if (kDebugProfileGuidedCompilation) {
+    LOG(INFO) << "[ProfileGuidedCompilation] "
+        << (result ? "Verified" : "Skipped") << " method:"
+        << dex_file.GetClassDescriptor(dex_file.GetClassDef(class_idx));
+  }
+  return result;
+}
+
 class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor {
  public:
   ResolveCatchBlockExceptionsClassVisitor(
@@ -2197,6 +2218,10 @@
     ATRACE_CALL();
     ScopedObjectAccess soa(Thread::Current());
     const DexFile& dex_file = *manager_->GetDexFile();
+    if (!manager_->GetCompiler()->ShouldVerifyClassBasedOnProfile(dex_file, class_def_index)) {
+      // Skip verification since the class is not in the profile.
+      return;
+    }
     const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
     const char* descriptor = dex_file.GetClassDescriptor(class_def);
     ClassLinker* class_linker = manager_->GetClassLinker();
@@ -2665,6 +2690,7 @@
       case mirror::Class::kStatusRetryVerificationAtRuntime:
       case mirror::Class::kStatusVerified:
       case mirror::Class::kStatusInitialized:
+      case mirror::Class::kStatusResolved:
         break;  // Expected states.
       default:
         LOG(FATAL) << "Unexpected class status for class "